summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-06-02 19:47:04 +0000
committerChris Lattner <sabre@nondot.org>2007-06-02 19:47:04 +0000
commita45c5af87b57dceec8532aa71ad537f4ea902b0c (patch)
tree0a9564c52fb09393ddd31d934d4a22d66b923396 /clang/CodeGen
parentf0106d25785985add9f55a6f22f0f8771f8538d2 (diff)
downloadbcm5719-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.cpp18
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.
OpenPOWER on IntegriCloud