[llvm-commits] [gcc-plugin] r81241 - in /gcc-plugin/trunk: llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Tue Sep 8 12:15:59 PDT 2009
Author: baldrick
Date: Tue Sep 8 14:15:58 2009
New Revision: 81241
URL: http://llvm.org/viewvc/llvm-project?rev=81241&view=rev
Log:
Refactor emission of comparisons, reducing code
duplication.
Modified:
gcc-plugin/trunk/llvm-convert.cpp
gcc-plugin/trunk/llvm-internal.h
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=81241&r1=81240&r2=81241&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Tue Sep 8 14:15:58 2009
@@ -959,41 +959,24 @@
// Binary Operators
case LT_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_ULT, ICmpInst::ICMP_SLT,
- FCmpInst::FCMP_OLT);
- break;
case LE_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_ULE, ICmpInst::ICMP_SLE,
- FCmpInst::FCMP_OLE);
- break;
case GT_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_UGT, ICmpInst::ICMP_SGT,
- FCmpInst::FCMP_OGT);
- break;
case GE_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_UGE, ICmpInst::ICMP_SGE,
- FCmpInst::FCMP_OGE);
- break;
case EQ_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_EQ, ICmpInst::ICMP_EQ,
- FCmpInst::FCMP_OEQ);
- break;
case NE_EXPR:
- Result = EmitCompare(exp, ICmpInst::ICMP_NE, ICmpInst::ICMP_NE,
- FCmpInst::FCMP_UNE);
- break;
case UNORDERED_EXPR:
- Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_UNO);
- break;
case ORDERED_EXPR:
- Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_ORD);
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case LTGT_EXPR:
+ Result = EmitCompare(TREE_OPERAND(exp, 0), TREE_OPERAND(exp, 1),
+ TREE_CODE(exp));
+ // The GCC result may be of any integer type.
+ Result = Builder.CreateZExt(Result, ConvertType(TREE_TYPE(exp)));
break;
- case UNLT_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_ULT); break;
- case UNLE_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_ULE); break;
- case UNGT_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_UGT); break;
- case UNGE_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_UGE); break;
- case UNEQ_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_UEQ); break;
- case LTGT_EXPR: Result = EmitCompare(exp, 0, 0, FCmpInst::FCMP_ONE); break;
case PLUS_EXPR:
Result = EmitBinOp(exp, DestLoc,
FLOAT_TYPE_P(TREE_TYPE(exp)) ?
@@ -3287,17 +3270,63 @@
/// EmitCompare - Compare LHS with RHS using the appropriate comparison code.
/// The result is an i1 boolean.
-Value *TreeToLLVM::EmitCompare(tree lhs, tree rhs,
- unsigned UIOpc, unsigned SIOpc, unsigned FPPred) {
- tree lhs_ty = TREE_TYPE(lhs);
- tree rhs_ty = TREE_TYPE(rhs);
-
- if (TREE_CODE(lhs_ty) == COMPLEX_TYPE) {
- // TODO: Reduce duplication with EmitComplexBinOp.
- const Type *ComplexTy = ConvertType(lhs_ty);
+Value *TreeToLLVM::EmitCompare(tree lhs, tree rhs, tree_code code) {
+ const Type *LHSTy = ConvertType(TREE_TYPE(lhs));
+ const Type *RHSTy = ConvertType(TREE_TYPE(rhs));
+
+ assert((LHSTy == RHSTy ||
+ (isa<PointerType>(LHSTy) && isa<PointerType>(RHSTy))) &&
+ "Unexpected types for comparison");
- MemRef LHSTmp = CreateTempLoc(ComplexTy);
- MemRef RHSTmp = CreateTempLoc(ComplexTy);
+ // Compute the LLVM opcodes corresponding to the GCC comparison.
+ CmpInst::Predicate UIPred = CmpInst::BAD_ICMP_PREDICATE;
+ CmpInst::Predicate SIPred = CmpInst::BAD_ICMP_PREDICATE;
+ CmpInst::Predicate FPPred = CmpInst::BAD_FCMP_PREDICATE;
+
+ switch (code) {
+ default:
+ assert(false && "Unhandled condition code!");
+ case LT_EXPR:
+ UIPred = CmpInst::ICMP_ULT;
+ SIPred = CmpInst::ICMP_SLT;
+ FPPred = CmpInst::FCMP_OLT;
+ break;
+ case LE_EXPR:
+ UIPred = CmpInst::ICMP_ULE;
+ SIPred = CmpInst::ICMP_SLE;
+ FPPred = CmpInst::FCMP_OLE;
+ break;
+ case GT_EXPR:
+ UIPred = CmpInst::ICMP_UGT;
+ SIPred = CmpInst::ICMP_SGT;
+ FPPred = CmpInst::FCMP_OGT;
+ break;
+ case GE_EXPR:
+ UIPred = CmpInst::ICMP_UGE;
+ SIPred = CmpInst::ICMP_SGE;
+ FPPred = CmpInst::FCMP_OGE;
+ break;
+ case EQ_EXPR:
+ UIPred = SIPred = CmpInst::ICMP_EQ;
+ FPPred = CmpInst::FCMP_OEQ;
+ break;
+ case NE_EXPR:
+ UIPred = SIPred = CmpInst::ICMP_NE;
+ FPPred = CmpInst::FCMP_UNE;
+ break;
+ case UNORDERED_EXPR: FPPred = CmpInst::FCMP_UNO; break;
+ case ORDERED_EXPR: FPPred = CmpInst::FCMP_ORD; break;
+ case UNLT_EXPR: FPPred = CmpInst::FCMP_ULT; break;
+ case UNLE_EXPR: FPPred = CmpInst::FCMP_ULE; break;
+ case UNGT_EXPR: FPPred = CmpInst::FCMP_UGT; break;
+ case UNGE_EXPR: FPPred = CmpInst::FCMP_UGE; break;
+ case UNEQ_EXPR: FPPred = CmpInst::FCMP_UEQ; break;
+ case LTGT_EXPR: FPPred = CmpInst::FCMP_ONE; break;
+ }
+
+ if (TREE_CODE(TREE_TYPE(lhs)) == COMPLEX_TYPE) {
+ MemRef LHSTmp = CreateTempLoc(LHSTy);
+ MemRef RHSTmp = CreateTempLoc(RHSTy);
Emit(lhs, &LHSTmp);
Emit(rhs, &RHSTmp);
@@ -3308,64 +3337,36 @@
Value *DSTr, *DSTi;
if (LHSr->getType()->isFloatingPoint()) {
- DSTr = Builder.CreateFCmp(FCmpInst::Predicate(FPPred), LHSr, RHSr);
- DSTi = Builder.CreateFCmp(FCmpInst::Predicate(FPPred), LHSi, RHSi);
- if (FPPred == FCmpInst::FCMP_OEQ)
+ DSTr = Builder.CreateFCmp(FPPred, LHSr, RHSr);
+ DSTi = Builder.CreateFCmp(FPPred, LHSi, RHSi);
+ if (FPPred == CmpInst::FCMP_OEQ)
return Builder.CreateAnd(DSTr, DSTi);
- assert(FPPred == FCmpInst::FCMP_UNE && "Unhandled complex comparison!");
+ assert(FPPred == CmpInst::FCMP_UNE && "Unhandled complex comparison!");
return Builder.CreateOr(DSTr, DSTi);
}
- assert(SIOpc == UIOpc && "(In)equality comparison depends on sign!");
- DSTr = Builder.CreateICmp(ICmpInst::Predicate(UIOpc), LHSr, RHSr);
- DSTi = Builder.CreateICmp(ICmpInst::Predicate(UIOpc), LHSi, RHSi);
- if (UIOpc == ICmpInst::ICMP_EQ)
+ assert(SIPred == UIPred && "(In)equality comparison depends on sign!");
+ DSTr = Builder.CreateICmp(UIPred, LHSr, RHSr);
+ DSTi = Builder.CreateICmp(UIPred, LHSi, RHSi);
+ if (UIPred == CmpInst::ICMP_EQ)
return Builder.CreateAnd(DSTr, DSTi);
- assert(UIOpc == ICmpInst::ICMP_NE && "Unhandled complex comparison!");
+ assert(UIPred == CmpInst::ICMP_NE && "Unhandled complex comparison!");
return Builder.CreateOr(DSTr, DSTi);
}
// Get the compare operands in the right type. Comparison of struct is not
// allowed, so this is safe as we already handled complex (struct) type.
Value *LHS = Emit(lhs, 0);
- Value *RHS = Emit(rhs, 0);
- bool LHSIsSigned = !TYPE_UNSIGNED(lhs_ty);
- bool RHSIsSigned = !TYPE_UNSIGNED(rhs_ty);
-
- // If one of the type conversions is useless, perform the other conversion.
- if (useless_type_conversion_p(lhs_ty, rhs_ty))
- RHS = CastToAnyType(RHS, RHSIsSigned, LHS->getType(), LHSIsSigned);
- else
- LHS = CastToAnyType(LHS, LHSIsSigned, RHS->getType(), RHSIsSigned);
+ Value *RHS = Builder.CreateBitCast(Emit(rhs, 0), LHSTy);
- if (FLOAT_TYPE_P(lhs_ty))
- return Builder.CreateFCmp(FCmpInst::Predicate(FPPred), LHS, RHS);
+ if (LHSTy->isFloatingPoint())
+ return Builder.CreateFCmp(FPPred, LHS, RHS);
// Determine which predicate to use based on signedness.
- ICmpInst::Predicate pred = ICmpInst::Predicate(LHSIsSigned ? SIOpc : UIOpc);
+ CmpInst::Predicate pred = TYPE_UNSIGNED(TREE_TYPE(lhs)) ? UIPred : SIPred;
return Builder.CreateICmp(pred, LHS, RHS);
}
-/// EmitCompare - 'exp' is a comparison of two values. Opc is the base LLVM
-/// comparison to use. isUnord is true if this is a floating point comparison
-/// that should also be true if either operand is a NaN. Note that Opc can be
-/// set to zero for special cases.
-///
-/// If DestTy is specified, make sure to return the result with the specified
-/// integer type. Otherwise, return the expression as whatever TREE_TYPE(exp)
-/// corresponds to.
-Value *TreeToLLVM::EmitCompare(tree exp, unsigned UIOpc, unsigned SIOpc,
- unsigned FPPred, const Type *DestTy) {
- Value *Result = EmitCompare(TREE_OPERAND(exp, 0), TREE_OPERAND(exp, 1),
- UIOpc, SIOpc, FPPred);
-
- if (DestTy == 0)
- DestTy = ConvertType(TREE_TYPE(exp));
-
- // The GCC type is probably an int, not a bool. ZExt to the right size.
- return Builder.CreateZExt(Result, DestTy);
-}
-
/// EmitBinOp - 'exp' is a binary operator.
///
Value *TreeToLLVM::EmitBinOp(tree exp, const MemRef *DestLoc, unsigned Opc) {
@@ -6315,24 +6316,6 @@
DSTi = Builder.CreateFDiv(Tmp9, Tmp6);
break;
}
- case EQ_EXPR: // (a+ib) == (c+id) = (a == c) & (b == d)
- if (LHSr->getType()->isFloatingPoint()) {
- DSTr = Builder.CreateFCmpOEQ(LHSr, RHSr, "tmpr");
- DSTi = Builder.CreateFCmpOEQ(LHSi, RHSi, "tmpi");
- } else {
- DSTr = Builder.CreateICmpEQ(LHSr, RHSr, "tmpr");
- DSTi = Builder.CreateICmpEQ(LHSi, RHSi, "tmpi");
- }
- return Builder.CreateAnd(DSTr, DSTi);
- case NE_EXPR: // (a+ib) != (c+id) = (a != c) | (b != d)
- if (LHSr->getType()->isFloatingPoint()) {
- DSTr = Builder.CreateFCmpUNE(LHSr, RHSr, "tmpr");
- DSTi = Builder.CreateFCmpUNE(LHSi, RHSi, "tmpi");
- } else {
- DSTr = Builder.CreateICmpNE(LHSr, RHSr, "tmpr");
- DSTi = Builder.CreateICmpNE(LHSi, RHSi, "tmpi");
- }
- return Builder.CreateOr(DSTr, DSTi);
}
EmitStoreToComplex(*DestLoc, DSTr, DSTi);
@@ -8086,54 +8069,9 @@
//===----------------------------------------------------------------------===//
void TreeToLLVM::RenderGIMPLE_COND(gimple stmt) {
- // Compute the LLVM opcodes corresponding to the GCC comparison.
- unsigned UIPred = 0, SIPred = 0, FPPred = 0;
- switch (gimple_cond_code(stmt)) {
- case LT_EXPR:
- UIPred = ICmpInst::ICMP_ULT;
- SIPred = ICmpInst::ICMP_SLT;
- FPPred = FCmpInst::FCMP_OLT;
- break;
- case LE_EXPR:
- UIPred = ICmpInst::ICMP_ULE;
- SIPred = ICmpInst::ICMP_SLE;
- FPPred = FCmpInst::FCMP_OLE;
- break;
- case GT_EXPR:
- UIPred = ICmpInst::ICMP_UGT;
- SIPred = ICmpInst::ICMP_SGT;
- FPPred = FCmpInst::FCMP_OGT;
- break;
- case GE_EXPR:
- UIPred = ICmpInst::ICMP_UGE;
- SIPred = ICmpInst::ICMP_SGE;
- FPPred = FCmpInst::FCMP_OGE;
- break;
- case EQ_EXPR:
- UIPred = SIPred = ICmpInst::ICMP_EQ;
- FPPred = FCmpInst::FCMP_OEQ;
- break;
- case NE_EXPR:
- UIPred = SIPred = ICmpInst::ICMP_NE;
- FPPred = FCmpInst::FCMP_UNE;
- break;
- case UNORDERED_EXPR: FPPred = FCmpInst::FCMP_UNO; break;
- case ORDERED_EXPR: FPPred = FCmpInst::FCMP_ORD; break;
- case UNLT_EXPR: FPPred = FCmpInst::FCMP_ULT; break;
- case UNLE_EXPR: FPPred = FCmpInst::FCMP_ULE; break;
- case UNGT_EXPR: FPPred = FCmpInst::FCMP_UGT; break;
- case UNGE_EXPR: FPPred = FCmpInst::FCMP_UGE; break;
- case UNEQ_EXPR: FPPred = FCmpInst::FCMP_UEQ; break;
- case LTGT_EXPR: FPPred = FCmpInst::FCMP_ONE; break;
-
- default:
- dump(stmt);
- llvm_unreachable("Unhandled condition code!");
- }
-
// Emit the comparison.
Value *Cond = EmitCompare(gimple_cond_lhs(stmt), gimple_cond_rhs(stmt),
- UIPred, SIPred, FPPred);
+ gimple_cond_code(stmt));
// Extract the target basic blocks.
edge true_edge, false_edge;
Modified: gcc-plugin/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-internal.h?rev=81241&r1=81240&r2=81241&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-internal.h (original)
+++ gcc-plugin/trunk/llvm-internal.h Tue Sep 8 14:15:58 2009
@@ -562,10 +562,7 @@
Value *EmitBIT_NOT_EXPR(tree_node *exp);
Value *EmitTRUTH_NOT_EXPR(tree_node *exp);
Value *EmitEXACT_DIV_EXPR(tree_node *exp, const MemRef *DestLoc);
- Value *EmitCompare(tree_node *lhs, tree_node *rhs,
- unsigned UIPred, unsigned SIPred, unsigned FPPred);
- Value *EmitCompare(tree_node *exp, unsigned UIPred, unsigned SIPred,
- unsigned FPPred, const Type *DestTy = 0);
+ Value *EmitCompare(tree_node *lhs, tree_node *rhs, tree_code code);
Value *EmitBinOp(tree_node *exp, const MemRef *DestLoc, unsigned Opc);
Value *EmitPtrBinOp(tree_node *exp, unsigned Opc);
Value *EmitTruthOp(tree_node *exp, unsigned Opc);
More information about the llvm-commits
mailing list