[cfe-commits] r39524 - in /cfe/cfe/trunk: CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h include/clang/AST/Stmt.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:45:16 PDT 2007
Author: clattner
Date: Wed Jul 11 11:45:16 2007
New Revision: 39524
URL: http://llvm.org/viewvc/llvm-project?rev=39524&view=rev
Log:
Implement codegen support for labels and gotos. We now compile:
void test1() {
foo:
goto foo;
goto foo;
goto foo;
}
void test() {
goto l;
l:
;
}
into:
define void @test1() {
entry:
br label %foo
foo: ; preds = %0, %foo, %entry
br label %foo
; No predecessors!
br label %foo
; No predecessors!
}
define void @test() {
entry:
br label %l
l: ; preds = %entry
}
Modified:
cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
cfe/cfe/trunk/include/clang/AST/Stmt.h
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp?rev=39524&r1=39523&r2=39524&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp Wed Jul 11 11:45:16 2007
@@ -25,6 +25,15 @@
: CGM(cgm), Target(CGM.getContext().Target) {}
+llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
+ BasicBlock *&BB = LabelMap[S];
+ if (BB) return BB;
+
+ // Create, but don't insert, the new block.
+ return BB = new BasicBlock(S->getName());
+}
+
+
/// ConvertType - Convert the specified type to its LLVM form.
const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
// FIXME: Cache these, move the CodeGenModule, expand, etc.
@@ -104,11 +113,11 @@
void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
const llvm::Type *Ty = ConvertType(FD->getType(), FD->getLocation());
- llvm::Function *F = new Function(cast<llvm::FunctionType>(Ty),
- Function::ExternalLinkage,
- FD->getName(), &CGM.getModule());
+ CurFn = new Function(cast<llvm::FunctionType>(Ty),
+ Function::ExternalLinkage,
+ FD->getName(), &CGM.getModule());
- BasicBlock *EntryBB = new BasicBlock("entry", F);
+ BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
// TODO: Walk the decls, creating allocas etc.
@@ -132,6 +141,8 @@
break;
case Stmt::NullStmtClass: break;
case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
+ case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
+ case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
}
}
@@ -143,3 +154,29 @@
EmitStmt(*I);
}
+void CodeGenFunction::EmitBlock(BasicBlock *BB) {
+ // Emit a branch from this block to the next one if this was a real block. If
+ // this was just a fall-through block after a terminator, don't emit it.
+ if (!Builder.GetInsertBlock()->empty() ||
+ Builder.GetInsertBlock()->getValueName()) {
+ Builder.CreateBr(BB);
+ } else {
+ // TODO: cache and reuse these.
+ Builder.GetInsertBlock()->eraseFromParent();
+ }
+ CurFn->getBasicBlockList().push_back(BB);
+ Builder.SetInsertPoint(BB);
+}
+
+void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
+ llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
+
+ EmitBlock(NextBB);
+}
+
+void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
+ Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
+
+ Builder.SetInsertPoint(new BasicBlock("", CurFn));
+}
+
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39524&r1=39523&r2=39524&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:45:16 2007
@@ -14,6 +14,7 @@
#ifndef CODEGEN_CODEGENFUNCTION_H
#define CODEGEN_CODEGENFUNCTION_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/LLVMBuilder.h"
namespace llvm {
@@ -26,6 +27,8 @@
class TargetInfo;
class Stmt;
class CompoundStmt;
+ class LabelStmt;
+ class GotoStmt;
namespace CodeGen {
class CodeGenModule;
@@ -36,6 +39,10 @@
CodeGenModule &CGM; // Per-module state.
TargetInfo &Target;
LLVMBuilder Builder;
+ llvm::Function *CurFn;
+
+ /// LabelMap - This keeps track of the LLVM basic block for each C label.
+ DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
public:
CodeGenFunction(CodeGenModule &cgm);
@@ -43,12 +50,22 @@
void GenerateCode(const FunctionDecl *FD);
+
+ /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
+ /// label maps to.
+ llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
+
+
+ void EmitBlock(BasicBlock *BB);
+
//===--------------------------------------------------------------------===//
// Statement Emission
//===--------------------------------------------------------------------===//
void EmitStmt(const Stmt *S);
void EmitCompoundStmt(const CompoundStmt &S);
+ void EmitLabelStmt(const LabelStmt &S);
+ void EmitGotoStmt(const GotoStmt &S);
};
} // end namespace CodeGen
} // end namespace clang
Modified: cfe/cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Stmt.h?rev=39524&r1=39523&r2=39524&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Stmt.h Wed Jul 11 11:45:16 2007
@@ -293,7 +293,7 @@
public:
GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
- LabelStmt *getLabel() { return Label; }
+ LabelStmt *getLabel() const { return Label; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
More information about the cfe-commits
mailing list