[cfe-commits] r39533 - in /cfe/cfe/trunk: CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h include/clang/AST/Expr.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:45:21 PDT 2007


Author: clattner
Date: Wed Jul 11 11:45:20 2007
New Revision: 39533

URL: http://llvm.org/viewvc/llvm-project?rev=39533&view=rev
Log:
Add support for codegen'ing paren exprs and if stmts.  We can now codegen:

void test() {
  goto l;

l:
  if (11) {
    j: ;
  }
}

into:

define void @test() {
entry:
        br label %l

l:              ; preds = %entry
        icmp ne i32 11, 0               ; <i1>:0 [#uses=1]
        br i1 %0, label %ifthen, label %ifend

ifthen:         ; preds = %l
        br label %j

j:              ; preds = %ifthen
        br label %ifend

ifend:          ; preds = %j, %l
}

whoa... :)

Modified:
    cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
    cfe/cfe/trunk/CodeGen/CodeGenFunction.h
    cfe/cfe/trunk/include/clang/AST/Expr.h

Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp?rev=39533&r1=39532&r2=39533&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp Wed Jul 11 11:45:20 2007
@@ -150,6 +150,7 @@
   case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
   case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
   case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
+  case Stmt::IfStmtClass:       EmitIfStmt(cast<IfStmt>(*S));             break;
   }
 }
 
@@ -164,12 +165,17 @@
 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 {
+  BasicBlock *LastBB = Builder.GetInsertBlock();
+  
+  if (LastBB->getTerminator()) {
+    // If the previous block is already terminated, don't touch it.
+  } else if (LastBB->empty() && LastBB->getValueName() == 0) {
+    // If the last block was an empty placeholder, remove it now.
     // TODO: cache and reuse these.
     Builder.GetInsertBlock()->eraseFromParent();
+  } else {
+    // Otherwise, create a fall-through branch.
+    Builder.CreateBr(BB);
   }
   CurFn->getBasicBlockList().push_back(BB);
   Builder.SetInsertPoint(BB);
@@ -179,14 +185,106 @@
   llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
   
   EmitBlock(NextBB);
+  EmitStmt(S.getSubStmt());
 }
 
 void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
   Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
   
+  // Emit a block after the branch so that dead code after a goto has some place
+  // to go.
   Builder.SetInsertPoint(new BasicBlock("", CurFn));
 }
 
+void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
+  // Emit the if condition.
+  ExprResult CondVal = EmitExpr(S.getCond());
+  QualType CondTy = S.getCond()->getType().getCanonicalType();
+  
+  // C99 6.8.4.1: The first substatement is executed if the expression compares
+  // unequal to 0.  The condition must be a scalar type.
+  llvm::Value *BoolCondVal;
+  
+  // MOVE this to a helper method, to share with for/while, assign to bool, etc.
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CondTy)) {
+    switch (BT->getKind()) {
+    default: assert(0 && "Unknown scalar value");
+    case BuiltinType::Bool:
+      BoolCondVal = CondVal.getVal();
+      // Bool is already evaluated right.
+      assert(BoolCondVal->getType() == llvm::Type::Int1Ty &&
+             "Unexpected bool value type!");
+      break;
+    case BuiltinType::Char:
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong: {
+      // Compare against zero for integers.
+      BoolCondVal = CondVal.getVal();
+      llvm::Value *Zero = Constant::getNullValue(BoolCondVal->getType());
+      BoolCondVal = Builder.CreateICmpNE(BoolCondVal, Zero);
+      break;
+    }
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble: {
+      // Compare against 0.0 for fp scalars.
+      BoolCondVal = CondVal.getVal();
+      llvm::Value *Zero = Constant::getNullValue(BoolCondVal->getType());
+      // FIXME: llvm-gcc produces a une comparison: validate this is right.
+      BoolCondVal = Builder.CreateFCmpUNE(BoolCondVal, Zero);
+      break;
+    }
+      
+    case BuiltinType::FloatComplex:
+    case BuiltinType::DoubleComplex:
+    case BuiltinType::LongDoubleComplex:
+      assert(0 && "comparisons against complex not implemented yet");
+    }
+  } else if (isa<PointerType>(CondTy)) {
+    BoolCondVal = CondVal.getVal();
+    llvm::Value *NullPtr = Constant::getNullValue(BoolCondVal->getType());
+    BoolCondVal = Builder.CreateICmpNE(BoolCondVal, NullPtr);
+    
+  } else {
+    const TagType *TT = cast<TagType>(CondTy);
+    assert(TT->getDecl()->getKind() == Decl::Enum && "Unknown scalar type");
+    // Compare against zero.
+    BoolCondVal = CondVal.getVal();
+    llvm::Value *Zero = Constant::getNullValue(BoolCondVal->getType());
+    BoolCondVal = Builder.CreateICmpNE(BoolCondVal, Zero);
+  }
+  
+  BasicBlock *ContBlock = new BasicBlock("ifend");
+  BasicBlock *ThenBlock = new BasicBlock("ifthen");
+  BasicBlock *ElseBlock = ContBlock;
+  
+  if (S.getElse())
+    ElseBlock = new BasicBlock("ifelse");
+  
+  // Insert the conditional branch.
+  Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
+  
+  // Emit the 'then' code.
+  EmitBlock(ThenBlock);
+  EmitStmt(S.getThen());
+  Builder.CreateBr(ContBlock);
+  
+  // Emit the 'else' code if present.
+  if (const Stmt *Else = S.getElse()) {
+    EmitBlock(ElseBlock);
+    EmitStmt(Else);
+    Builder.CreateBr(ContBlock);
+  }
+  
+  // Emit the continuation block for code after the if.
+  EmitBlock(ContBlock);
+}
 
 
 //===--------------------------------------------------------------------===//
@@ -201,6 +299,8 @@
     printf("Unimplemented expr!\n");
     E->dump();
     return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
+  case Stmt::ParenExprClass:
+    return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
   case Stmt::IntegerLiteralClass:
     return EmitIntegerLiteral(cast<IntegerLiteral>(E)); 
   }

Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39533&r1=39532&r2=39533&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:45:20 2007
@@ -29,6 +29,7 @@
   class CompoundStmt;
   class LabelStmt;
   class GotoStmt;
+  class IfStmt;
   
   class Expr;
   class IntegerLiteral;
@@ -36,20 +37,36 @@
 namespace CodeGen {
   class CodeGenModule;
   
-struct ExprResult {
+class ExprResult {
   Value *V;
-  bool isAggregate;
+  bool IsAggregate;
+public:
+  
+  bool isAggregate() const { return IsAggregate; }
+  bool isScalar() const { return !IsAggregate; }
+  
+  /// getVal() - Return the Value* of this scalar value.
+  Value *getVal() const {
+    assert(!isAggregate() && "Not a scalar!");
+    return V;
+  }
+
+  /// getAggregateVal() - Return the Value* of the address of the aggregate.
+  Value *getAggregateVal() const {
+    assert(isAggregate() && "Not an aggregate!");
+    return V;
+  }
   
   static ExprResult get(Value *V) {
     ExprResult ER;
     ER.V = V;
-    ER.isAggregate = false;
+    ER.IsAggregate = false;
     return ER;
   }
   static ExprResult getAggregate(Value *V) {
     ExprResult ER;
     ER.V = V;
-    ER.isAggregate = true;
+    ER.IsAggregate = true;
     return ER;
   }
 };
@@ -87,7 +104,7 @@
   void EmitCompoundStmt(const CompoundStmt &S);
   void EmitLabelStmt(const LabelStmt &S);
   void EmitGotoStmt(const GotoStmt &S);
-  
+  void EmitIfStmt(const IfStmt &S);
   
   //===--------------------------------------------------------------------===//
   //                             Expression Emission

Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39533&r1=39532&r2=39533&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:45:20 2007
@@ -206,7 +206,8 @@
   ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
     : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {}
   
-  Expr *getSubExpr() const { return Val; }
+  const Expr *getSubExpr() const { return Val; }
+  Expr *getSubExpr() { return Val; }
   SourceRange getSourceRange() const { return SourceRange(L, R); }
 
   virtual void visit(StmtVisitor &Visitor);





More information about the cfe-commits mailing list