diff options
author | Chris Lattner <sabre@nondot.org> | 2007-06-02 19:47:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-06-02 19:47:04 +0000 |
commit | a45c5af87b57dceec8532aa71ad537f4ea902b0c (patch) | |
tree | 0a9564c52fb09393ddd31d934d4a22d66b923396 /clang/CodeGen | |
parent | f0106d25785985add9f55a6f22f0f8771f8538d2 (diff) | |
download | bcm5719-llvm-a45c5af87b57dceec8532aa71ad537f4ea902b0c.tar.gz bcm5719-llvm-a45c5af87b57dceec8532aa71ad537f4ea902b0c.zip |
Implement a trivial optimization to reduce the number of compares emitted.
For:
register short X;
if (!X) {
We now produce:
%tmp = load i16* %X ; <i16> [#uses=1]
%tobool = icmp ne i16 %tmp, 0 ; <i1> [#uses=1]
%lnot = xor i1 %tobool, true ; <i1> [#uses=1]
br i1 %lnot, label %ifthen, label %ifend
instead of:
%tmp = load i16* %X ; <i16> [#uses=1]
%tobool = icmp ne i16 %tmp, 0 ; <i1> [#uses=1]
%lnot = xor i1 %tobool, true ; <i1> [#uses=1]
%lnot.ext = zext i1 %lnot to i32 ; <i32> [#uses=1]
%tobool1 = icmp ne i32 %lnot.ext, 0 ; <i1> [#uses=1]
br i1 %tobool1, label %ifthen, label %ifend
llvm-svn: 39560
Diffstat (limited to 'clang/CodeGen')
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 94f0f2d02e2..84a9b5f28b0 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -75,13 +75,25 @@ Value *CodeGenFunction::EvaluateScalarValueToBool(ExprResult Val, QualType Ty) { // Usual case for integers, pointers, and enums: compare against zero. Result = Val.getVal(); + + // Because of the type rules of C, we often end up computing a logical value, + // then zero extending it to int, then wanting it as a logical value again. + // Optimize this common case. + if (llvm::ZExtInst *ZI = dyn_cast<ZExtInst>(Result)) { + if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) { + Result = ZI->getOperand(0); + ZI->eraseFromParent(); + return Result; + } + } + llvm::Value *Zero = Constant::getNullValue(Result->getType()); return Builder.CreateICmpNE(Result, Zero, "tobool"); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // LValue Expression Emission -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// LValue CodeGenFunction::EmitLValue(const Expr *E) { switch (E->getStmtClass()) { @@ -171,6 +183,8 @@ ExprResult CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) { Value *BoolVal = EvaluateScalarValueToBool(Op, E->getSubExpr()->getType()); // Invert value. + // TODO: Could dynamically modify easy computations here. For example, if + // the operand is an icmp ne, turn into icmp eq. BoolVal = Builder.CreateNot(BoolVal, "lnot"); // ZExt result to int. |