[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