[cfe-commits] r39559 - in /cfe/cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CGStmt.cpp CodeGen/CodeGenFunction.h include/clang/AST/Expr.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:45:36 PDT 2007
Author: clattner
Date: Wed Jul 11 11:45:35 2007
New Revision: 39559
URL: http://llvm.org/viewvc/llvm-project?rev=39559&view=rev
Log:
Refactor EvaluateScalarValueToBool out of if statement emission, so it can
be shared.
Implement infrastructure for unary operator emission.
Implement basic logical not support. We now compile:
register short X;
if (!X) {
into:
%tmp = load i16* %X ; <i16> [#uses=1]
%tobool = icmp ne i16 %tmp, 0 ; <i1> [#uses=1]
%lnot = xor i1 %tobool, true ; <i1> [#uses=1]
zext i1 %lnot to i32 ; <i32>:0 [#uses=1]
%tobool1 = icmp ne i32 %0, 0 ; <i1> [#uses=1]
br i1 %tobool1, label %ifthen, label %ifend
Modified:
cfe/cfe/trunk/CodeGen/CGExpr.cpp
cfe/cfe/trunk/CodeGen/CGStmt.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
cfe/cfe/trunk/include/clang/AST/Expr.h
Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39559&r1=39558&r2=39559&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:45:35 2007
@@ -20,6 +20,66 @@
using namespace CodeGen;
//===--------------------------------------------------------------------===//
+// Miscellaneous Helper Methods
+//===--------------------------------------------------------------------===//
+
+/// EvaluateScalarValueToBool - Evaluate the specified expression value to a
+/// boolean (i1) truth value. This is equivalent to "Val == 0".
+Value *CodeGenFunction::EvaluateScalarValueToBool(ExprResult Val, QualType Ty) {
+ Ty = Ty.getCanonicalType();
+ Value *Result;
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(Ty)) {
+ switch (BT->getKind()) {
+ default: assert(0 && "Unknown scalar value");
+ case BuiltinType::Bool:
+ Result = Val.getVal();
+ // Bool is already evaluated right.
+ assert(Result->getType() == llvm::Type::Int1Ty &&
+ "Unexpected bool value type!");
+ return Result;
+ case BuiltinType::Char:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ case BuiltinType::Int:
+ case BuiltinType::UInt:
+ case BuiltinType::Long:
+ case BuiltinType::ULong:
+ case BuiltinType::LongLong:
+ case BuiltinType::ULongLong:
+ // Code below handles simple integers.
+ break;
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::LongDouble: {
+ // Compare against 0.0 for fp scalars.
+ Result = Val.getVal();
+ llvm::Value *Zero = Constant::getNullValue(Result->getType());
+ // FIXME: llvm-gcc produces a une comparison: validate this is right.
+ Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
+ return Result;
+ }
+
+ case BuiltinType::FloatComplex:
+ case BuiltinType::DoubleComplex:
+ case BuiltinType::LongDoubleComplex:
+ assert(0 && "comparisons against complex not implemented yet");
+ }
+ } else {
+ assert((isa<PointerType>(Ty) ||
+ cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) &&
+ "Unknown scalar type");
+ // Code below handles this fine.
+ }
+
+ // Usual case for integers, pointers, and enums: compare against zero.
+ Result = Val.getVal();
+ llvm::Value *Zero = Constant::getNullValue(Result->getType());
+ return Builder.CreateICmpNE(Result, Zero, "tobool");
+}
+
+//===--------------------------------------------------------------------===//
// LValue Expression Emission
//===--------------------------------------------------------------------===//
@@ -75,6 +135,8 @@
// Operators.
case Expr::ParenExprClass:
return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
+ case Expr::UnaryOperatorClass:
+ return EmitUnaryOperator(cast<UnaryOperator>(E));
case Expr::BinaryOperatorClass:
return EmitBinaryOperator(cast<BinaryOperator>(E));
}
@@ -85,6 +147,37 @@
return ExprResult::get(ConstantInt::get(E->getValue()));
}
+//===--------------------------------------------------------------------===//
+// Unary Operator Emission
+//===--------------------------------------------------------------------===//
+
+ExprResult CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) {
+ switch (E->getOpcode()) {
+ default:
+ printf("Unimplemented unary expr!\n");
+ E->dump();
+ return ExprResult::get(UndefValue::get(llvm::Type::Int32Ty));
+ case UnaryOperator::LNot: return EmitUnaryLNot(E);
+ }
+}
+
+/// C99 6.5.3.3
+ExprResult CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) {
+ ExprResult Op = EmitExpr(E->getSubExpr());
+
+ //UsualUnary();
+
+ // Compare to zero.
+ Value *BoolVal = EvaluateScalarValueToBool(Op, E->getSubExpr()->getType());
+
+ // Invert value.
+ BoolVal = Builder.CreateNot(BoolVal, "lnot");
+
+ // ZExt result to int.
+ const llvm::Type *ResTy = ConvertType(E->getType(), E->getOperatorLoc());
+ return ExprResult::get(Builder.CreateZExt(BoolVal, ResTy, "lnot.ext"));
+}
+
//===--------------------------------------------------------------------===//
// Binary Operator Emission
Modified: cfe/cfe/trunk/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGStmt.cpp?rev=39559&r1=39558&r2=39559&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGStmt.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGStmt.cpp Wed Jul 11 11:45:35 2007
@@ -97,62 +97,8 @@
// 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, "tobool");
- 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, "tobool");
- 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, "tobool");
-
- } 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, "tobool");
- }
+ llvm::Value *BoolCondVal =
+ EvaluateScalarValueToBool(CondVal, S.getCond()->getType());
BasicBlock *ContBlock = new BasicBlock("ifend");
BasicBlock *ThenBlock = new BasicBlock("ifthen");
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39559&r1=39558&r2=39559&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:45:35 2007
@@ -38,6 +38,7 @@
class Expr;
class DeclRefExpr;
class IntegerLiteral;
+ class UnaryOperator;
class BinaryOperator;
class BlockVarDecl;
@@ -125,6 +126,8 @@
/// LabelMap - This keeps track of the LLVM basic block for each C label.
DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
+
+ const llvm::Type *LLVMIntTy;
public:
CodeGenFunction(CodeGenModule &cgm);
@@ -141,6 +144,10 @@
void EmitBlock(BasicBlock *BB);
+ /// EvaluateScalarValueToBool - Evaluate the specified expression value to a
+ /// boolean (i1) truth value. This is equivalent to "Val == 0".
+ Value *EvaluateScalarValueToBool(ExprResult Val, QualType Ty);
+
//===--------------------------------------------------------------------===//
// Local Declaration Emission
//===--------------------------------------------------------------------===//
@@ -174,13 +181,17 @@
ExprResult EmitExpr(const Expr *E);
ExprResult EmitIntegerLiteral(const IntegerLiteral *E);
- ExprResult EmitBinaryOperator(const BinaryOperator *E);
void EmitUsualArithmeticConversions(const BinaryOperator *E,
ExprResult &LHS, ExprResult &RHS);
+ // Unary Operators.
+ ExprResult EmitUnaryOperator(const UnaryOperator *E);
+ ExprResult EmitUnaryLNot(const UnaryOperator *E);
+
// Binary Operators.
+ ExprResult EmitBinaryOperator(const BinaryOperator *E);
ExprResult EmitBinaryAdd(const BinaryOperator *E);
};
} // end namespace CodeGen
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=39559&r1=39558&r2=39559&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:45:35 2007
@@ -236,46 +236,50 @@
Real, Imag, // "__real expr"/"__imag expr" Extension.
Extension // __extension__ marker.
};
+private:
+ Expr *Val;
+ Opcode Opc;
+ SourceLocation Loc;
+public:
UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
: Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "sizeof" or "[pre]++"
- static const char *getOpcodeStr(Opcode Op);
+ Opcode getOpcode() const { return Opc; }
+ Expr *getSubExpr() const { return Val; }
+
+ /// getOperatorLoc - Return the location of the operator.
+ SourceLocation getOperatorLoc() const { return Loc; }
+
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op);
- static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
-
- Opcode getOpcode() const { return Opc; }
- Expr *getSubExpr() const { return Val; }
- virtual SourceRange getSourceRange() const {
- if (isPostfix())
- return SourceRange(Val->getLocStart(), Loc);
- else
- return SourceRange(Loc, Val->getLocEnd());
- }
bool isPostfix() const { return isPostfix(Opc); }
bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; }
+ static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
/// getDecl - a recursive routine that derives the base decl for an
/// expression. For example, it will return the declaration for "s" from
/// the following complex expression "s.zz[2].bb.vv".
static bool isAddressable(Expr *e);
+
+ /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+ /// corresponds to, e.g. "sizeof" or "[pre]++"
+ static const char *getOpcodeStr(Opcode Op);
+ virtual SourceRange getSourceRange() const {
+ if (isPostfix())
+ return SourceRange(Val->getLocStart(), Loc);
+ else
+ return SourceRange(Loc, Val->getLocEnd());
+ }
+
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryOperatorClass;
}
static bool classof(const UnaryOperator *) { return true; }
-
-private:
- Expr *Val;
- Opcode Opc;
- SourceLocation Loc;
};
/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
More information about the cfe-commits
mailing list