[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