diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/InstCombine/InstCombine.h | 12 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 294 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineCalls.cpp | 32 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineCompares.cpp | 17 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombinePHI.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 26 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 575 | ||||
-rw-r--r-- | lib/Transforms/Utils/BuildLibCalls.cpp | 324 | ||||
-rw-r--r-- | lib/Transforms/Utils/CMakeLists.txt | 1 |
9 files changed, 550 insertions, 733 deletions
diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h index 09accb6..07fb15e 100644 --- a/lib/Transforms/InstCombine/InstCombine.h +++ b/lib/Transforms/InstCombine/InstCombine.h @@ -117,11 +117,11 @@ public: Instruction *visitUDiv(BinaryOperator &I); Instruction *visitSDiv(BinaryOperator &I); Instruction *visitFDiv(BinaryOperator &I); - Instruction *FoldAndOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); - Instruction *FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, FCmpInst *RHS); + Value *FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS); + Value *FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS); Instruction *visitAnd(BinaryOperator &I); - Instruction *FoldOrOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); - Instruction *FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, FCmpInst *RHS); + Value *FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS); + Value *FoldOrOfFCmps(FCmpInst *LHS, FCmpInst *RHS); Instruction *FoldOrWithConstants(BinaryOperator &I, Value *Op, Value *A, Value *B, Value *C); Instruction *visitOr (BinaryOperator &I); @@ -327,8 +327,8 @@ private: Value *FoldLogicalPlusAnd(Value *LHS, Value *RHS, ConstantInt *Mask, bool isSub, Instruction &I); - Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, - bool isSigned, bool Inside, Instruction &IB); + Value *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, + bool isSigned, bool Inside); Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocaInst &AI); Instruction *MatchBSwap(BinaryOperator &I); bool SimplifyStoreAtEndOfBlock(StoreInst &SI); diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 86673f8..3fb3de7 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -137,80 +137,44 @@ static unsigned getFCmpCode(FCmpInst::Predicate CC, bool &isOrdered) { /// opcode and two operands into either a constant true or false, or a brand /// new ICmp instruction. The sign is passed in to determine which kind /// of predicate to use in the new icmp instruction. -static Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS) { +static Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS, + InstCombiner::BuilderTy *Builder) { + CmpInst::Predicate Pred; switch (Code) { default: assert(0 && "Illegal ICmp code!"); - case 0: - return ConstantInt::getFalse(LHS->getContext()); - case 1: - if (Sign) - return new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS); - return new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS); - case 2: - return new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS); - case 3: - if (Sign) - return new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS); - return new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS); - case 4: - if (Sign) - return new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS); - return new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS); - case 5: - return new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS); - case 6: - if (Sign) - return new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS); - return new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS); - case 7: - return ConstantInt::getTrue(LHS->getContext()); + case 0: // False. + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); + case 1: Pred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; + case 2: Pred = ICmpInst::ICMP_EQ; break; + case 3: Pred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; + case 4: Pred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; + case 5: Pred = ICmpInst::ICMP_NE; break; + case 6: Pred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; + case 7: // True. + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1); } + return Builder->CreateICmp(Pred, LHS, RHS); } /// getFCmpValue - This is the complement of getFCmpCode, which turns an /// opcode and two operands into either a FCmp instruction. isordered is passed /// in to determine which kind of predicate to use in the new fcmp instruction. static Value *getFCmpValue(bool isordered, unsigned code, - Value *LHS, Value *RHS) { + Value *LHS, Value *RHS, + InstCombiner::BuilderTy *Builder) { + CmpInst::Predicate Pred; switch (code) { - default: llvm_unreachable("Illegal FCmp code!"); - case 0: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_ORD, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_UNO, LHS, RHS); - case 1: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_OGT, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_UGT, LHS, RHS); - case 2: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_OEQ, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_UEQ, LHS, RHS); - case 3: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_OGE, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_UGE, LHS, RHS); - case 4: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_OLT, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_ULT, LHS, RHS); - case 5: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_ONE, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_UNE, LHS, RHS); - case 6: - if (isordered) - return new FCmpInst(FCmpInst::FCMP_OLE, LHS, RHS); - else - return new FCmpInst(FCmpInst::FCMP_ULE, LHS, RHS); - case 7: return ConstantInt::getTrue(LHS->getContext()); + default: assert(0 && "Illegal FCmp code!"); + case 0: Pred = isordered ? FCmpInst::FCMP_ORD : FCmpInst::FCMP_UNO; break; + case 1: Pred = isordered ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_UGT; break; + case 2: Pred = isordered ? FCmpInst::FCMP_OEQ : FCmpInst::FCMP_UEQ; break; + case 3: Pred = isordered ? FCmpInst::FCMP_OGE : FCmpInst::FCMP_UGE; break; + case 4: Pred = isordered ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_ULT; break; + case 5: Pred = isordered ? FCmpInst::FCMP_ONE : FCmpInst::FCMP_UNE; break; + case 6: Pred = isordered ? FCmpInst::FCMP_OLE : FCmpInst::FCMP_ULE; break; + case 7: return ConstantInt::getTrue(LHS->getContext()); } + return Builder->CreateFCmp(Pred, LHS, RHS); } /// PredicatesFoldable - Return true if both predicates match sign or if at @@ -355,40 +319,39 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, /// (V-Lo) <u Hi-Lo. This method expects that Lo <= Hi. isSigned indicates /// whether to treat the V, Lo and HI as signed or not. IB is the location to /// insert new instructions. -Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, - bool isSigned, bool Inside, - Instruction &IB) { +Value *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, + bool isSigned, bool Inside) { assert(cast<ConstantInt>(ConstantExpr::getICmp((isSigned ? ICmpInst::ICMP_SLE:ICmpInst::ICMP_ULE), Lo, Hi))->getZExtValue() && "Lo is not <= Hi in range emission code!"); if (Inside) { if (Lo == Hi) // Trivially false. - return new ICmpInst(ICmpInst::ICMP_NE, V, V); + return ConstantInt::getFalse(V->getContext()); // V >= Min && V < Hi --> V < Hi if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) { ICmpInst::Predicate pred = (isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT); - return new ICmpInst(pred, V, Hi); + return Builder->CreateICmp(pred, V, Hi); } // Emit V-Lo <u Hi-Lo Constant *NegLo = ConstantExpr::getNeg(Lo); Value *Add = Builder->CreateAdd(V, NegLo, V->getName()+".off"); Constant *UpperBound = ConstantExpr::getAdd(NegLo, Hi); - return new ICmpInst(ICmpInst::ICMP_ULT, Add, UpperBound); + return Builder->CreateICmpULT(Add, UpperBound); } if (Lo == Hi) // Trivially true. - return new ICmpInst(ICmpInst::ICMP_EQ, V, V); + return ConstantInt::getTrue(V->getContext()); // V < Min || V >= Hi -> V > Hi-1 Hi = SubOne(cast<ConstantInt>(Hi)); if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) { ICmpInst::Predicate pred = (isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT); - return new ICmpInst(pred, V, Hi); + return Builder->CreateICmp(pred, V, Hi); } // Emit V-Lo >u Hi-1-Lo @@ -396,7 +359,7 @@ Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, ConstantInt *NegLo = cast<ConstantInt>(ConstantExpr::getNeg(Lo)); Value *Add = Builder->CreateAdd(V, NegLo, V->getName()+".off"); Constant *LowerBound = ConstantExpr::getAdd(NegLo, Hi); - return new ICmpInst(ICmpInst::ICMP_UGT, Add, LowerBound); + return Builder->CreateICmpUGT(Add, LowerBound); } // isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with @@ -472,8 +435,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS, } /// FoldAndOfICmps - Fold (icmp)&(icmp) if possible. -Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, - ICmpInst *LHS, ICmpInst *RHS) { +Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) { ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate(); // (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B) @@ -486,11 +448,7 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1); unsigned Code = getICmpCode(LHS) & getICmpCode(RHS); bool isSigned = LHS->isSigned() || RHS->isSigned(); - Value *RV = getICmpValue(isSigned, Code, Op0, Op1); - if (Instruction *I = dyn_cast<Instruction>(RV)) - return I; - // Otherwise, it's a constant boolean value. - return ReplaceInstUsesWith(I, RV); + return getICmpValue(isSigned, Code, Op0, Op1, Builder); } } @@ -506,13 +464,13 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, if (LHSCC == ICmpInst::ICMP_ULT && LHSCst->getValue().isPowerOf2()) { Value *NewOr = Builder->CreateOr(Val, Val2); - return new ICmpInst(LHSCC, NewOr, LHSCst); + return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0) if (LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero()) { Value *NewOr = Builder->CreateOr(Val, Val2); - return new ICmpInst(LHSCC, NewOr, LHSCst); + return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } } @@ -562,33 +520,32 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, case ICmpInst::ICMP_EQ: // (X == 13 & X == 15) -> false case ICmpInst::ICMP_UGT: // (X == 13 & X > 15) -> false case ICmpInst::ICMP_SGT: // (X == 13 & X > 15) -> false - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); case ICmpInst::ICMP_NE: // (X == 13 & X != 15) -> X == 13 case ICmpInst::ICMP_ULT: // (X == 13 & X < 15) -> X == 13 case ICmpInst::ICMP_SLT: // (X == 13 & X < 15) -> X == 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; } case ICmpInst::ICMP_NE: switch (RHSCC) { default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_ULT: if (LHSCst == SubOne(RHSCst)) // (X != 13 & X u< 14) -> X < 13 - return new ICmpInst(ICmpInst::ICMP_ULT, Val, LHSCst); + return Builder->CreateICmpULT(Val, LHSCst); break; // (X != 13 & X u< 15) -> no change case ICmpInst::ICMP_SLT: if (LHSCst == SubOne(RHSCst)) // (X != 13 & X s< 14) -> X < 13 - return new ICmpInst(ICmpInst::ICMP_SLT, Val, LHSCst); + return Builder->CreateICmpSLT(Val, LHSCst); break; // (X != 13 & X s< 15) -> no change case ICmpInst::ICMP_EQ: // (X != 13 & X == 15) -> X == 15 case ICmpInst::ICMP_UGT: // (X != 13 & X u> 15) -> X u> 15 case ICmpInst::ICMP_SGT: // (X != 13 & X s> 15) -> X s> 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; case ICmpInst::ICMP_NE: if (LHSCst == SubOne(RHSCst)){// (X != 13 & X != 14) -> X-13 >u 1 Constant *AddCST = ConstantExpr::getNeg(LHSCst); Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off"); - return new ICmpInst(ICmpInst::ICMP_UGT, Add, - ConstantInt::get(Add->getType(), 1)); + return Builder->CreateICmpUGT(Add, ConstantInt::get(Add->getType(), 1)); } break; // (X != 13 & X != 15) -> no change } @@ -598,12 +555,12 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X u< 13 & X == 15) -> false case ICmpInst::ICMP_UGT: // (X u< 13 & X u> 15) -> false - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); case ICmpInst::ICMP_SGT: // (X u< 13 & X s> 15) -> no change break; case ICmpInst::ICMP_NE: // (X u< 13 & X != 15) -> X u< 13 case ICmpInst::ICMP_ULT: // (X u< 13 & X u< 15) -> X u< 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; case ICmpInst::ICMP_SLT: // (X u< 13 & X s< 15) -> no change break; } @@ -613,12 +570,12 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X s< 13 & X == 15) -> false case ICmpInst::ICMP_SGT: // (X s< 13 & X s> 15) -> false - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); case ICmpInst::ICMP_UGT: // (X s< 13 & X u> 15) -> no change break; case ICmpInst::ICMP_NE: // (X s< 13 & X != 15) -> X < 13 case ICmpInst::ICMP_SLT: // (X s< 13 & X s< 15) -> X < 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; case ICmpInst::ICMP_ULT: // (X s< 13 & X u< 15) -> no change break; } @@ -628,16 +585,15 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X u> 13 & X == 15) -> X == 15 case ICmpInst::ICMP_UGT: // (X u> 13 & X u> 15) -> X u> 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; case ICmpInst::ICMP_SGT: // (X u> 13 & X s> 15) -> no change break; case ICmpInst::ICMP_NE: if (RHSCst == AddOne(LHSCst)) // (X u> 13 & X != 14) -> X u> 14 - return new ICmpInst(LHSCC, Val, RHSCst); + return Builder->CreateICmp(LHSCC, Val, RHSCst); break; // (X u> 13 & X != 15) -> no change case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) <u 1 - return InsertRangeTest(Val, AddOne(LHSCst), - RHSCst, false, true, I); + return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, false, true); case ICmpInst::ICMP_SLT: // (X u> 13 & X s< 15) -> no change break; } @@ -647,16 +603,15 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X s> 13 & X == 15) -> X == 15 case ICmpInst::ICMP_SGT: // (X s> 13 & X s> 15) -> X s> 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; case ICmpInst::ICMP_UGT: // (X s> 13 & X u> 15) -> no change break; case ICmpInst::ICMP_NE: if (RHSCst == AddOne(LHSCst)) // (X s> 13 & X != 14) -> X s> 14 - return new ICmpInst(LHSCC, Val, RHSCst); + return Builder->CreateICmp(LHSCC, Val, RHSCst); break; // (X s> 13 & X != 15) -> no change case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) s< 1 - return InsertRangeTest(Val, AddOne(LHSCst), - RHSCst, true, true, I); + return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, true, true); case ICmpInst::ICMP_ULT: // (X s> 13 & X u< 15) -> no change break; } @@ -666,9 +621,10 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I, return 0; } -Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, - FCmpInst *RHS) { - +/// FoldAndOfFCmps - Optimize (fcmp)&(fcmp). NOTE: Unlike the rest of +/// instcombine, this returns a Value which should already be inserted into the +/// function. +Value *InstCombiner::FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS) { if (LHS->getPredicate() == FCmpInst::FCMP_ORD && RHS->getPredicate() == FCmpInst::FCMP_ORD) { // (fcmp ord x, c) & (fcmp ord y, c) -> (fcmp ord x, y) @@ -677,17 +633,15 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, // If either of the constants are nans, then the whole thing returns // false. if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN()) - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); - return new FCmpInst(FCmpInst::FCMP_ORD, - LHS->getOperand(0), RHS->getOperand(0)); + return ConstantInt::getFalse(LHS->getContext()); + return Builder->CreateFCmpORD(LHS->getOperand(0), RHS->getOperand(0)); } // Handle vector zeros. This occurs because the canonical form of // "fcmp ord x,x" is "fcmp ord x, 0". if (isa<ConstantAggregateZero>(LHS->getOperand(1)) && isa<ConstantAggregateZero>(RHS->getOperand(1))) - return new FCmpInst(FCmpInst::FCMP_ORD, - LHS->getOperand(0), RHS->getOperand(0)); + return Builder->CreateFCmpORD(LHS->getOperand(0), RHS->getOperand(0)); return 0; } @@ -705,14 +659,13 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, if (Op0LHS == Op1LHS && Op0RHS == Op1RHS) { // Simplify (fcmp cc0 x, y) & (fcmp cc1 x, y). if (Op0CC == Op1CC) - return new FCmpInst((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS); - + return Builder->CreateFCmp((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS); if (Op0CC == FCmpInst::FCMP_FALSE || Op1CC == FCmpInst::FCMP_FALSE) - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); if (Op0CC == FCmpInst::FCMP_TRUE) - return ReplaceInstUsesWith(I, RHS); + return RHS; if (Op1CC == FCmpInst::FCMP_TRUE) - return ReplaceInstUsesWith(I, LHS); + return LHS; bool Op0Ordered; bool Op1Ordered; @@ -727,14 +680,14 @@ Instruction *InstCombiner::FoldAndOfFCmps(Instruction &I, FCmpInst *LHS, // uno && ueq -> uno && (uno || eq) -> ueq // ord && olt -> ord && (ord && lt) -> olt if (Op0Ordered == Op1Ordered) - return ReplaceInstUsesWith(I, RHS); + return RHS; // uno && oeq -> uno && (ord && eq) -> false // uno && ord -> false if (!Op0Ordered) - return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); // ord && ueq -> ord && (uno || eq) -> oeq - return cast<Instruction>(getFCmpValue(true, Op1Pred, Op0LHS, Op0RHS)); + return getFCmpValue(true, Op1Pred, Op0LHS, Op0RHS, Builder); } } @@ -930,14 +883,14 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1)) if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0)) - if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS)) - return Res; + if (Value *Res = FoldAndOfICmps(LHS, RHS)) + return ReplaceInstUsesWith(I, Res); // If and'ing two fcmp, try combine them into one. if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1))) - if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS)) - return Res; + if (Value *Res = FoldAndOfFCmps(LHS, RHS)) + return ReplaceInstUsesWith(I, Res); // fold (and (cast A), (cast B)) -> (cast (and A, B)) @@ -960,19 +913,15 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { // cast is otherwise not optimizable. This happens for vector sexts. if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp)) if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp)) - if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS)) { - InsertNewInstBefore(Res, I); + if (Value *Res = FoldAndOfICmps(LHS, RHS)) return CastInst::Create(Op0C->getOpcode(), Res, I.getType()); - } // If this is and(cast(fcmp), cast(fcmp)), try to fold this even if the // cast is otherwise not optimizable. This happens for vector sexts. if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp)) if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp)) - if (Instruction *Res = FoldAndOfFCmps(I, LHS, RHS)) { - InsertNewInstBefore(Res, I); + if (Value *Res = FoldAndOfFCmps(LHS, RHS)) return CastInst::Create(Op0C->getOpcode(), Res, I.getType()); - } } } @@ -1179,8 +1128,7 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B, } /// FoldOrOfICmps - Fold (icmp)|(icmp) if possible. -Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, - ICmpInst *LHS, ICmpInst *RHS) { +Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) { ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate(); // (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B) @@ -1193,11 +1141,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1); unsigned Code = getICmpCode(LHS) | getICmpCode(RHS); bool isSigned = LHS->isSigned() || RHS->isSigned(); - Value *RV = getICmpValue(isSigned, Code, Op0, Op1); - if (Instruction *I = dyn_cast<Instruction>(RV)) - return I; - // Otherwise, it's a constant boolean value. - return ReplaceInstUsesWith(I, RV); + return getICmpValue(isSigned, Code, Op0, Op1, Builder); } } @@ -1211,7 +1155,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, if (LHSCst == RHSCst && LHSCC == RHSCC && LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero()) { Value *NewOr = Builder->CreateOr(Val, Val2); - return new ICmpInst(LHSCC, NewOr, LHSCst); + return Builder->CreateICmp(LHSCC, NewOr, LHSCst); } // From here on, we only handle: @@ -1263,7 +1207,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, Constant *AddCST = ConstantExpr::getNeg(LHSCst); Value *Add = Builder->CreateAdd(Val, AddCST, Val->getName()+".off"); AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst); - return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST); + return Builder->CreateICmpULT(Add, AddCST); } break; // (X == 13 | X == 15) -> no change case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change @@ -1272,7 +1216,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, case ICmpInst::ICMP_NE: // (X == 13 | X != 15) -> X != 15 case ICmpInst::ICMP_ULT: // (X == 13 | X u< 15) -> X u< 15 case ICmpInst::ICMP_SLT: // (X == 13 | X s< 15) -> X s< 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; } break; case ICmpInst::ICMP_NE: @@ -1281,11 +1225,11 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, case ICmpInst::ICMP_EQ: // (X != 13 | X == 15) -> X != 13 case ICmpInst::ICMP_UGT: // (X != 13 | X u> 15) -> X != 13 case ICmpInst::ICMP_SGT: // (X != 13 | X s> 15) -> X != 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; case ICmpInst::ICMP_NE: // (X != 13 | X != 15) -> true case ICmpInst::ICMP_ULT: // (X != 13 | X u< 15) -> true case ICmpInst::ICMP_SLT: // (X != 13 | X s< 15) -> true - return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext())); + return ConstantInt::getTrue(LHS->getContext()); } break; case ICmpInst::ICMP_ULT: @@ -1297,14 +1241,13 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, // If RHSCst is [us]MAXINT, it is always false. Not handling // this can cause overflow. if (RHSCst->isMaxValue(false)) - return ReplaceInstUsesWith(I, LHS); - return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), - false, false, I); + return LHS; + return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), false, false); case ICmpInst::ICMP_SGT: // (X u< 13 | X s> 15) -> no change break; case ICmpInst::ICMP_NE: // (X u< 13 | X != 15) -> X != 15 case ICmpInst::ICMP_ULT: // (X u< 13 | X u< 15) -> X u< 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; case ICmpInst::ICMP_SLT: // (X u< 13 | X s< 15) -> no change break; } @@ -1318,14 +1261,13 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, // If RHSCst is [us]MAXINT, it is always false. Not handling // this can cause overflow. if (RHSCst->isMaxValue(true)) - return ReplaceInstUsesWith(I, LHS); - return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), - true, false, I); + return LHS; + return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), true, false); case ICmpInst::ICMP_UGT: // (X s< 13 | X u> 15) -> no change break; case ICmpInst::ICMP_NE: // (X s< 13 | X != 15) -> X != 15 case ICmpInst::ICMP_SLT: // (X s< 13 | X s< 15) -> X s< 15 - return ReplaceInstUsesWith(I, RHS); + return RHS; case ICmpInst::ICMP_ULT: // (X s< 13 | X u< 15) -> no change break; } @@ -1335,12 +1277,12 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X u> 13 | X == 15) -> X u> 13 case ICmpInst::ICMP_UGT: // (X u> 13 | X u> 15) -> X u> 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; case ICmpInst::ICMP_SGT: // (X u> 13 | X s> 15) -> no change break; case ICmpInst::ICMP_NE: // (X u> 13 | X != 15) -> true case ICmpInst::ICMP_ULT: // (X u> 13 | X u< 15) -> true - return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext())); + return ConstantInt::getTrue(LHS->getContext()); case ICmpInst::ICMP_SLT: // (X u> 13 | X s< 15) -> no change break; } @@ -1350,12 +1292,12 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X s> 13 | X == 15) -> X > 13 case ICmpInst::ICMP_SGT: // (X s> 13 | X s> 15) -> X > 13 - return ReplaceInstUsesWith(I, LHS); + return LHS; case ICmpInst::ICMP_UGT: // (X s> 13 | X u> 15) -> no change break; case ICmpInst::ICMP_NE: // (X s> 13 | X != 15) -> true case ICmpInst::ICMP_SLT: // (X s> 13 | X s< 15) -> true - return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext())); + return ConstantInt::getTrue(LHS->getContext()); case ICmpInst::ICMP_ULT: // (X s> 13 | X u< 15) -> no change break; } @@ -1364,8 +1306,10 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I, return 0; } -Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, - FCmpInst *RHS) { +/// FoldOrOfFCmps - Optimize (fcmp)|(fcmp). NOTE: Unlike the rest of +/// instcombine, this returns a Value which should already be inserted into the +/// function. +Value *InstCombiner::FoldOrOfFCmps(FCmpInst *LHS, FCmpInst *RHS) { if (LHS->getPredicate() == FCmpInst::FCMP_UNO && RHS->getPredicate() == FCmpInst::FCMP_UNO && LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType()) { @@ -1374,20 +1318,18 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, // If either of the constants are nans, then the whole thing returns // true. if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN()) - return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext())); + return ConstantInt::getTrue(LHS->getContext()); // Otherwise, no need to compare the two constants, compare the // rest. - return new FCmpInst(FCmpInst::FCMP_UNO, - LHS->getOperand(0), RHS->getOperand(0)); + return Builder->CreateFCmpUNO(LHS->getOperand(0), RHS->getOperand(0)); } // Handle vector zeros. This occurs because the canonical form of // "fcmp uno x,x" is "fcmp uno x, 0". if (isa<ConstantAggregateZero>(LHS->getOperand(1)) && isa<ConstantAggregateZero>(RHS->getOperand(1))) - return new FCmpInst(FCmpInst::FCMP_UNO, - LHS->getOperand(0), RHS->getOperand(0)); + return Builder->CreateFCmpUNO(LHS->getOperand(0), RHS->getOperand(0)); return 0; } @@ -1404,14 +1346,13 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, if (Op0LHS == Op1LHS && Op0RHS == Op1RHS) { // Simplify (fcmp cc0 x, y) | (fcmp cc1 x, y). if (Op0CC == Op1CC) - return new FCmpInst((FCmpInst::Predicate)Op0CC, - Op0LHS, Op0RHS); + return Builder->CreateFCmp((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS); if (Op0CC == FCmpInst::FCMP_TRUE || Op1CC == FCmpInst::FCMP_TRUE) - return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext())); + return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1); if (Op0CC == FCmpInst::FCMP_FALSE) - return ReplaceInstUsesWith(I, RHS); + return RHS; if (Op1CC == FCmpInst::FCMP_FALSE) - return ReplaceInstUsesWith(I, LHS); + return LHS; bool Op0Ordered; bool Op1Ordered; unsigned Op0Pred = getFCmpCode(Op0CC, Op0Ordered); @@ -1419,11 +1360,7 @@ Instruction *InstCombiner::FoldOrOfFCmps(Instruction &I, FCmpInst *LHS, if (Op0Ordered == Op1Ordered) { // If both are ordered or unordered, return a new fcmp with // or'ed predicates. - Value *RV = getFCmpValue(Op0Ordered, Op0Pred|Op1Pred, Op0LHS, Op0RHS); - if (Instruction *I = dyn_cast<Instruction>(RV)) - return I; - // Otherwise, it's a constant boolean value... - return ReplaceInstUsesWith(I, RV); + return getFCmpValue(Op0Ordered, Op0Pred|Op1Pred, Op0LHS, Op0RHS, Builder); } } return 0; @@ -1686,14 +1623,14 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1))) if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0))) - if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS)) - return Res; + if (Value *Res = FoldOrOfICmps(LHS, RHS)) + return ReplaceInstUsesWith(I, Res); // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y) if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1))) - if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS)) - return Res; + if (Value *Res = FoldOrOfFCmps(LHS, RHS)) + return ReplaceInstUsesWith(I, Res); // fold (or (cast A), (cast B)) -> (cast (or A, B)) if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) { @@ -1717,19 +1654,15 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { // cast is otherwise not optimizable. This happens for vector sexts. if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1COp)) if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0COp)) - if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS)) { - InsertNewInstBefore(Res, I); + if (Value *Res = FoldOrOfICmps(LHS, RHS)) return CastInst::Create(Op0C->getOpcode(), Res, I.getType()); - } // If this is or(cast(fcmp), cast(fcmp)), try to fold this even if the // cast is otherwise not optimizable. This happens for vector sexts. if (FCmpInst *RHS = dyn_cast<FCmpInst>(Op1COp)) if (FCmpInst *LHS = dyn_cast<FCmpInst>(Op0COp)) - if (Instruction *Res = FoldOrOfFCmps(I, LHS, RHS)) { - InsertNewInstBefore(Res, I); + if (Value *Res = FoldOrOfFCmps(LHS, RHS)) return CastInst::Create(Op0C->getOpcode(), Res, I.getType()); - } } } } @@ -2005,11 +1938,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1); unsigned Code = getICmpCode(LHS) ^ getICmpCode(RHS); bool isSigned = LHS->isSigned() || RHS->isSigned(); - Value *RV = getICmpValue(isSigned, Code, Op0, Op1); - if (Instruction *I = dyn_cast<Instruction>(RV)) - return I; - // Otherwise, it's a constant boolean value. - return ReplaceInstUsesWith(I, RV); + return ReplaceInstUsesWith(I, + getICmpValue(isSigned, Code, Op0, Op1, Builder)); } } diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 835d149..a241f169 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -304,29 +304,39 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { switch (II->getIntrinsicID()) { default: break; case Intrinsic::objectsize: { - const Type *ReturnTy = CI.getType(); - Value *Op1 = II->getOperand(1); - bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1); - // We need target data for just about everything so depend on it. if (!TD) break; + const Type *ReturnTy = CI.getType(); + bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1); + // Get to the real allocated thing and offset as fast as possible. - Op1 = Op1->stripPointerCasts(); + Value *Op1 = II->getOperand(1)->stripPointerCasts(); // If we've stripped down to a single global variable that we // can know the size of then just return that. if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) { if (GV->hasDefinitiveInitializer()) { Constant *C = GV->getInitializer(); - uint64_t globalSize = TD->getTypeAllocSize(C->getType()); - return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize)); + uint64_t GlobalSize = TD->getTypeAllocSize(C->getType()); + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, GlobalSize)); } else { + // Can't determine size of the GV. Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); return ReplaceInstUsesWith(CI, RetVal); } - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) { - + } else if (AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) { + // Get alloca size. + if (AI->getAllocatedType()->isSized()) { + uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType()); + if (AI->isArrayAllocation()) { + const ConstantInt *C = dyn_cast<ConstantInt>(AI->getArraySize()); + if (!C) break; + AllocaSize *= C->getZExtValue(); + } + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, AllocaSize)); + } + } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op1)) { // Only handle constant GEPs here. if (CE->getOpcode() != Instruction::GetElementPtr) break; GEPOperator *GEP = cast<GEPOperator>(CE); @@ -361,6 +371,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { return ReplaceInstUsesWith(CI, RetVal); } + + // Do not return "I don't know" here. Later optimization passes could + // make it possible to evaluate objectsize to a constant. + break; } case Intrinsic::bswap: // bswap(bswap(x)) -> x diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 518af74..72fd558 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -877,25 +877,26 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI, case ICmpInst::ICMP_EQ: if (LoOverflow && HiOverflow) return ReplaceInstUsesWith(ICI, ConstantInt::getFalse(ICI.getContext())); - else if (HiOverflow) + if (HiOverflow) return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, X, LoBound); - else if (LoOverflow) + if (LoOverflow) return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, true, ICI); + return ReplaceInstUsesWith(ICI, + InsertRangeTest(X, LoBound, HiBound, DivIsSigned, + true)); case ICmpInst::ICMP_NE: if (LoOverflow && HiOverflow) return ReplaceInstUsesWith(ICI, ConstantInt::getTrue(ICI.getContext())); - else if (HiOverflow) + if (HiOverflow) return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, X, LoBound); - else if (LoOverflow) + if (LoOverflow) return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, false, ICI); + return ReplaceInstUsesWith(ICI, InsertRangeTest(X, LoBound, HiBound, + DivIsSigned, false)); case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: if (LoOverflow == +1) // Low bound is greater than input range. diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp index fba8354..65f0393 100644 --- a/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -266,6 +266,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { // and if TD isn't around, we can't handle the mixed case. bool isVolatile = FirstLI->isVolatile(); unsigned LoadAlignment = FirstLI->getAlignment(); + unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace(); // We can't sink the load if the loaded value could be modified between the // load and the PHI. @@ -290,6 +291,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) { // the load and the PHI. if (LI->isVolatile() != isVolatile || LI->getParent() != PN.getIncomingBlock(i) || + LI->getPointerAddressSpace() != LoadAddrSpace || !isSafeAndProfitableToSinkLoad(LI)) return 0; diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 12827b6..5aca9cdc 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -597,19 +597,35 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { /// FindSingleUseMultiplyFactors - If V is a single-use multiply, recursively /// add its operands as factors, otherwise add V to the list of factors. +/// +/// Ops is the top-level list of add operands we're trying to factor. static void FindSingleUseMultiplyFactors(Value *V, - SmallVectorImpl<Value*> &Factors) { + SmallVectorImpl<Value*> &Factors, + const SmallVectorImpl<ValueEntry> &Ops, + bool IsRoot) { BinaryOperator *BO; - if ((!V->hasOneUse() && !V->use_empty()) || + if (!(V->hasOneUse() || V->use_empty()) || // More than one use. !(BO = dyn_cast<BinaryOperator>(V)) || BO->getOpcode() != Instruction::Mul) { Factors.push_back(V); return; } + // If this value has a single use because it is another input to the add + // tree we're reassociating and we dropped its use, it actually has two + // uses and we can't factor it. + if (!IsRoot) { + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + if (Ops[i].Op == V) { + Factors.push_back(V); + return; + } + } + + // Otherwise, add the LHS and RHS to the list of factors. - FindSingleUseMultiplyFactors(BO->getOperand(1), Factors); - FindSingleUseMultiplyFactors(BO->getOperand(0), Factors); + FindSingleUseMultiplyFactors(BO->getOperand(1), Factors, Ops, false); + FindSingleUseMultiplyFactors(BO->getOperand(0), Factors, Ops, false); } /// OptimizeAndOrXor - Optimize a series of operands to an 'and', 'or', or 'xor' @@ -753,7 +769,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I, // Compute all of the factors of this added value. SmallVector<Value*, 8> Factors; - FindSingleUseMultiplyFactors(BOp, Factors); + FindSingleUseMultiplyFactors(BOp, Factors, Ops, true); assert(Factors.size() > 1 && "Bad linearize!"); // Add one to FactorOccurrences for each unique factor in this op. diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index cde214b..86ddeac 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -17,6 +17,7 @@ #define DEBUG_TYPE "simplify-libcalls" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/BuildLibCalls.h" #include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" @@ -67,496 +68,14 @@ public: Context = &CI->getCalledFunction()->getContext(); return CallOptimizer(CI->getCalledFunction(), CI, B); } - - /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. - Value *CastToCStr(Value *V, IRBuilder<> &B); - - /// EmitStrLen - Emit a call to the strlen function to the builder, for the - /// specified pointer. Ptr is required to be some pointer type, and the - /// return value has 'intptr_t' type. - Value *EmitStrLen(Value *Ptr, IRBuilder<> &B); - - /// EmitStrChr - Emit a call to the strchr function to the builder, for the - /// specified pointer and character. Ptr is required to be some pointer type, - /// and the return value has 'i8*' type. - Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B); - - /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the - /// specified pointer arguments. - Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B); - - /// EmitMemCpy - Emit a call to the memcpy function to the builder. This - /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. - Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len, - unsigned Align, IRBuilder<> &B); - - /// EmitMemMove - Emit a call to the memmove function to the builder. This - /// always expects that the size has type 'intptr_t' and Dst/Src are pointers. - Value *EmitMemMove(Value *Dst, Value *Src, Value *Len, - unsigned Align, IRBuilder<> &B); - - /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is - /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. - Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B); - - /// EmitMemCmp - Emit a call to the memcmp function. - Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B); - - /// EmitMemSet - Emit a call to the memset function - Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, IRBuilder<> &B); - - /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' - /// (e.g. 'floor'). This function is known to take a single of type matching - /// 'Op' and returns one value with the same type. If 'Op' is a long double, - /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f' - /// suffix. - Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B, - const AttrListPtr &Attrs); - - /// EmitPutChar - Emit a call to the putchar function. This assumes that Char - /// is an integer. - Value *EmitPutChar(Value *Char, IRBuilder<> &B); - - /// EmitPutS - Emit a call to the puts function. This assumes that Str is - /// some pointer. - void EmitPutS(Value *Str, IRBuilder<> &B); - - /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is - /// an i32, and File is a pointer to FILE. - void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B); - - /// EmitFPutS - Emit a call to the puts function. Str is required to be a - /// pointer and File is a pointer to FILE. - void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B); - - /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is - /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. - void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B); - }; } // End anonymous namespace. -/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. -Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) { - return B.CreateBitCast(V, Type::getInt8PtrTy(*Context), "cstr"); -} - -/// EmitStrLen - Emit a call to the strlen function to the builder, for the -/// specified pointer. This always returns an integer value of size intptr_t. -Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[2]; - AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly | - Attribute::NoUnwind); - - Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2), - TD->getIntPtrType(*Context), - Type::getInt8PtrTy(*Context), - NULL); - CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen"); - if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -/// EmitStrChr - Emit a call to the strchr function to the builder, for the -/// specified pointer and character. Ptr is required to be some pointer type, -/// and the return value has 'i8*' type. -Value *LibCallOptimization::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI = - AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); - - const Type *I8Ptr = Type::getInt8PtrTy(*Context); - const Type *I32Ty = Type::getInt32Ty(*Context); - Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1), - I8Ptr, I8Ptr, I32Ty, NULL); - CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), - ConstantInt::get(I32Ty, C), "strchr"); - if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the -/// specified pointer arguments. -Value *LibCallOptimization::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[2]; - AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); - const Type *I8Ptr = Type::getInt8PtrTy(*Context); - Value *StrCpy = M->getOrInsertFunction("strcpy", AttrListPtr::get(AWI, 2), - I8Ptr, I8Ptr, I8Ptr, NULL); - CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), - "strcpy"); - if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always -/// expects that the size has type 'intptr_t' and Dst/Src are pointers. -Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, - unsigned Align, IRBuilder<> &B) { - Module *M = Caller->getParent(); - const Type *Ty = Len->getType(); - Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, &Ty, 1); - Dst = CastToCStr(Dst, B); - Src = CastToCStr(Src, B); - return B.CreateCall4(MemCpy, Dst, Src, Len, - ConstantInt::get(Type::getInt32Ty(*Context), Align)); -} - -/// EmitMemMove - Emit a call to the memmove function to the builder. This -/// always expects that the size has type 'intptr_t' and Dst/Src are pointers. -Value *LibCallOptimization::EmitMemMove(Value *Dst, Value *Src, Value *Len, - unsigned Align, IRBuilder<> &B) { - Module *M = Caller->getParent(); - const Type *Ty = TD->getIntPtrType(*Context); - Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, &Ty, 1); - Dst = CastToCStr(Dst, B); - Src = CastToCStr(Src, B); - Value *A = ConstantInt::get(Type::getInt32Ty(*Context), Align); - return B.CreateCall4(MemMove, Dst, Src, Len, A); -} - -/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is -/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. -Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val, - Value *Len, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI; - AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); - - Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1), - Type::getInt8PtrTy(*Context), - Type::getInt8PtrTy(*Context), - Type::getInt32Ty(*Context), - TD->getIntPtrType(*Context), - NULL); - CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); - - if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -/// EmitMemCmp - Emit a call to the memcmp function. -Value *LibCallOptimization::EmitMemCmp(Value *Ptr1, Value *Ptr2, - Value *Len, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[3]; - AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); - AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly | - Attribute::NoUnwind); - - Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3), - Type::getInt32Ty(*Context), - Type::getInt8PtrTy(*Context), - Type::getInt8PtrTy(*Context), - TD->getIntPtrType(*Context), NULL); - CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), - Len, "memcmp"); - - if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -/// EmitMemSet - Emit a call to the memset function -Value *LibCallOptimization::EmitMemSet(Value *Dst, Value *Val, - Value *Len, IRBuilder<> &B) { - Module *M = Caller->getParent(); - Intrinsic::ID IID = Intrinsic::memset; - const Type *Tys[1]; - Tys[0] = Len->getType(); - Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1); - Value *Align = ConstantInt::get(Type::getInt32Ty(*Context), 1); - return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align); -} - -/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. -/// 'floor'). This function is known to take a single of type matching 'Op' and -/// returns one value with the same type. If 'Op' is a long double, 'l' is -/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. -Value *LibCallOptimization::EmitUnaryFloatFnCall(Value *Op, const char *Name, - IRBuilder<> &B, - const AttrListPtr &Attrs) { - char NameBuffer[20]; - if (!Op->getType()->isDoubleTy()) { - // If we need to add a suffix, copy into NameBuffer. - unsigned NameLen = strlen(Name); - assert(NameLen < sizeof(NameBuffer)-2); - memcpy(NameBuffer, Name, NameLen); - if (Op->getType()->isFloatTy()) - NameBuffer[NameLen] = 'f'; // floorf - else - NameBuffer[NameLen] = 'l'; // floorl - NameBuffer[NameLen+1] = 0; - Name = NameBuffer; - } - - Module *M = Caller->getParent(); - Value *Callee = M->getOrInsertFunction(Name, Op->getType(), - Op->getType(), NULL); - CallInst *CI = B.CreateCall(Callee, Op, Name); - CI->setAttributes(Attrs); - if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - - return CI; -} - -/// EmitPutChar - Emit a call to the putchar function. This assumes that Char -/// is an integer. -Value *LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) { - Module *M = Caller->getParent(); - Value *PutChar = M->getOrInsertFunction("putchar", Type::getInt32Ty(*Context), - Type::getInt32Ty(*Context), NULL); - CallInst *CI = B.CreateCall(PutChar, - B.CreateIntCast(Char, - Type::getInt32Ty(*Context), - /*isSigned*/true, - "chari"), - "putchar"); - - if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - return CI; -} - -/// EmitPutS - Emit a call to the puts function. This assumes that Str is -/// some pointer. -void LibCallOptimization::EmitPutS(Value *Str, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[2]; - AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); - - Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2), - Type::getInt32Ty(*Context), - Type::getInt8PtrTy(*Context), - NULL); - CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts"); - if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) - CI->setCallingConv(F->getCallingConv()); - -} - -/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is -/// an integer and File is a pointer to FILE. -void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[2]; - AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); - Constant *F; - if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), - Type::getInt32Ty(*Context), - Type::getInt32Ty(*Context), File->getType(), - NULL); - else - F = M->getOrInsertFunction("fputc", - Type::getInt32Ty(*Context), - Type::getInt32Ty(*Context), - File->getType(), NULL); - Char = B.CreateIntCast(Char, Type::getInt32Ty(*Context), /*isSigned*/true, - "chari"); - CallInst *CI = B.CreateCall2(F, Char, File, "fputc"); - - if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); -} - -/// EmitFPutS - Emit a call to the puts function. Str is required to be a -/// pointer and File is a pointer to FILE. -void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[3]; - AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); - AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); - Constant *F; - if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), - Type::getInt32Ty(*Context), - Type::getInt8PtrTy(*Context), - File->getType(), NULL); - else - F = M->getOrInsertFunction("fputs", Type::getInt32Ty(*Context), - Type::getInt8PtrTy(*Context), - File->getType(), NULL); - CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs"); - - if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); -} - -/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is -/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. -void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File, - IRBuilder<> &B) { - Module *M = Caller->getParent(); - AttributeWithIndex AWI[3]; - AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); - AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture); - AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); - Constant *F; - if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3), - TD->getIntPtrType(*Context), - Type::getInt8PtrTy(*Context), - TD->getIntPtrType(*Context), - TD->getIntPtrType(*Context), - File->getType(), NULL); - else - F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(*Context), - Type::getInt8PtrTy(*Context), - TD->getIntPtrType(*Context), - TD->getIntPtrType(*Context), - File->getType(), NULL); - CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size, - ConstantInt::get(TD->getIntPtrType(*Context), 1), File); - - if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) - CI->setCallingConv(Fn->getCallingConv()); -} //===----------------------------------------------------------------------===// // Helper Functions //===----------------------------------------------------------------------===// -/// GetStringLengthH - If we can compute the length of the string pointed to by -/// the specified pointer, return 'len+1'. If we can't, return 0. -static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) { - // Look through noop bitcast instructions. - if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) - return GetStringLengthH(BCI->getOperand(0), PHIs); - - // If this is a PHI node, there are two cases: either we have already seen it - // or we haven't. - if (PHINode *PN = dyn_cast<PHINode>(V)) { - if (!PHIs.insert(PN)) - return ~0ULL; // already in the set. - - // If it was new, see if all the input strings are the same length. - uint64_t LenSoFar = ~0ULL; - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs); - if (Len == 0) return 0; // Unknown length -> unknown. - - if (Len == ~0ULL) continue; - - if (Len != LenSoFar && LenSoFar != ~0ULL) - return 0; // Disagree -> unknown. - LenSoFar = Len; - } - - // Success, all agree. - return LenSoFar; - } - - // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y) - if (SelectInst *SI = dyn_cast<SelectInst>(V)) { - uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs); - if (Len1 == 0) return 0; - uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs); - if (Len2 == 0) return 0; - if (Len1 == ~0ULL) return Len2; - if (Len2 == ~0ULL) return Len1; - if (Len1 != Len2) return 0; - return Len1; - } - - // If the value is not a GEP instruction nor a constant expression with a - // GEP instruction, then return unknown. - User *GEP = 0; - if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) { - GEP = GEPI; - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() != Instruction::GetElementPtr) - return 0; - GEP = CE; - } else { - return 0; - } - - // Make sure the GEP has exactly three arguments. - if (GEP->getNumOperands() != 3) - return 0; - - // Check to make sure that the first operand of the GEP is an integer and - // has value 0 so that we are sure we're indexing into the initializer. - if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) { - if (!Idx->isZero()) - return 0; - } else - return 0; - - // If the second index isn't a ConstantInt, then this is a variable index - // into the array. If this occurs, we can't say anything meaningful about - // the string. - uint64_t StartIdx = 0; - if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2))) - StartIdx = CI->getZExtValue(); - else - return 0; - - // The GEP instruction, constant or instruction, must reference a global - // variable that is a constant and is initialized. The referenced constant - // initializer is the array that we'll use for optimization. - GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)); - if (!GV || !GV->isConstant() || !GV->hasInitializer() || - GV->mayBeOverridden()) - return 0; - Constant *GlobalInit = GV->getInitializer(); - - // Handle the ConstantAggregateZero case, which is a degenerate case. The - // initializer is constant zero so the length of the string must be zero. - if (isa<ConstantAggregateZero>(GlobalInit)) - return 1; // Len = 0 offset by 1. - - // Must be a Constant Array - ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit); - if (!Array || !Array->getType()->getElementType()->isIntegerTy(8)) - return false; - - // Get the number of elements in the array - uint64_t NumElts = Array->getType()->getNumElements(); - - // Traverse the constant array from StartIdx (derived above) which is - // the place the GEP refers to in the array. - for (unsigned i = StartIdx; i != NumElts; ++i) { - Constant *Elt = Array->getOperand(i); - ConstantInt *CI = dyn_cast<ConstantInt>(Elt); - if (!CI) // This array isn't suitable, non-int initializer. - return 0; - if (CI->isZero()) - return i-StartIdx+1; // We found end of string, success! - } - - return 0; // The array isn't null terminated, conservatively return 'unknown'. -} - -/// GetStringLength - If we can compute the length of the string pointed to by -/// the specified pointer, return 'len+1'. If we can't, return 0. -static uint64_t GetStringLength(Value *V) { - if (!V->getType()->isPointerTy()) return 0; - - SmallPtrSet<PHINode*, 32> PHIs; - uint64_t Len = GetStringLengthH(V, PHIs); - // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return - // an empty string as a length. - return Len == ~0ULL ? 1 : Len; -} - /// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the /// value is equal or not-equal to zero. static bool IsOnlyUsedInZeroEqualityComparison(Value *V) { @@ -613,7 +132,7 @@ struct StrCatOpt : public LibCallOptimization { void EmitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B) { // We need to find the end of the destination string. That's where the // memory is to be moved to. We just generate a call to strlen. - Value *DstLen = EmitStrLen(Dst, B); + Value *DstLen = EmitStrLen(Dst, B, TD); // Now that we have the destination's length, we must index into the // destination's pointer to get the actual memcpy destination (end of @@ -623,7 +142,7 @@ struct StrCatOpt : public LibCallOptimization { // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. EmitMemCpy(CpyDst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B); + ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B, TD); } }; @@ -701,7 +220,8 @@ struct StrChrOpt : public LibCallOptimization { return 0; return EmitMemChr(SrcStr, CI->getOperand(2), // include nul. - ConstantInt::get(TD->getIntPtrType(*Context), Len), B); + ConstantInt::get(TD->getIntPtrType(*Context), Len), + B, TD); } // Otherwise, the character is a constant, see if the first argument is @@ -772,7 +292,7 @@ struct StrCmpOpt : public LibCallOptimization { return EmitMemCmp(Str1P, Str2P, ConstantInt::get(TD->getIntPtrType(*Context), - std::min(Len1, Len2)), B); + std::min(Len1, Len2)), B, TD); } return 0; @@ -852,7 +372,7 @@ struct StrCpyOpt : public LibCallOptimization { // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. EmitMemCpy(Dst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B); + ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD); return Dst; } }; @@ -881,7 +401,7 @@ struct StrNCpyOpt : public LibCallOptimization { if (SrcLen == 0) { // strncpy(x, "", y) -> memset(x, '\0', y, 1) EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp, - B); + B, TD); return Dst; } @@ -901,7 +421,7 @@ struct StrNCpyOpt : public LibCallOptimization { // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant] EmitMemCpy(Dst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B); + ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD); return Dst; } @@ -993,7 +513,7 @@ struct StrStrOpt : public LibCallOptimization { // fold strstr(x, "y") -> strchr(x, 'y'). if (HasStr2 && ToFindStr.size() == 1) - return B.CreateBitCast(EmitStrChr(CI->getOperand(1), ToFindStr[0], B), + return B.CreateBitCast(EmitStrChr(CI->getOperand(1), ToFindStr[0], B, TD), CI->getType()); return 0; } @@ -1061,7 +581,8 @@ struct MemCpyOpt : public LibCallOptimization { return 0; // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1) - EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B); + EmitMemCpy(CI->getOperand(1), CI->getOperand(2), + CI->getOperand(3), 1, B, TD); return CI->getOperand(1); } }; @@ -1082,7 +603,8 @@ struct MemMoveOpt : public LibCallOptimization { return 0; // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) - EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B); + EmitMemMove(CI->getOperand(1), CI->getOperand(2), + CI->getOperand(3), 1, B, TD); return CI->getOperand(1); } }; @@ -1105,7 +627,7 @@ struct MemSetOpt : public LibCallOptimization { // memset(p, v, n) -> llvm.memset(p, v, n, 1) Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context), false); - EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B); + EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD); return CI->getOperand(1); } }; @@ -1130,11 +652,14 @@ struct MemCpyChkOpt : public LibCallOptimization { FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; - ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); - if (!SizeCI) + ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); + if (!ObjSizeCI) return 0; - if (SizeCI->isAllOnesValue()) { - EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B); + ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); + if (ObjSizeCI->isAllOnesValue() || + (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) { + EmitMemCpy(CI->getOperand(1), CI->getOperand(2), + CI->getOperand(3), 1, B, TD); return CI->getOperand(1); } @@ -1158,13 +683,15 @@ struct MemSetChkOpt : public LibCallOptimization { FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; - ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); - if (!SizeCI) + ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); + if (!ObjSizeCI) return 0; - if (SizeCI->isAllOnesValue()) { + ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); + if (ObjSizeCI->isAllOnesValue() || + (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) { Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context), false); - EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B); + EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD); return CI->getOperand(1); } @@ -1188,12 +715,14 @@ struct MemMoveChkOpt : public LibCallOptimization { FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; - ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); - if (!SizeCI) + ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4)); + if (!ObjSizeCI) return 0; - if (SizeCI->isAllOnesValue()) { + ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); + if (ObjSizeCI->isAllOnesValue() || + (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) { EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), - 1, B); + 1, B, TD); return CI->getOperand(1); } @@ -1209,8 +738,8 @@ struct StrCpyChkOpt : public LibCallOptimization { !FT->getParamType(1)->isPointerTy()) return 0; - ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); - if (!SizeCI) + ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); + if (!ObjSizeCI) return 0; // If a) we don't have any length information, or b) we know this will @@ -1218,9 +747,9 @@ struct StrCpyChkOpt : public LibCallOptimization { // strcpy_chk call which may fail at runtime if the size is too long. // TODO: It might be nice to get a maximum length out of the possible // string lengths for varying. - if (SizeCI->isAllOnesValue() || - SizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2))) - return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B); + if (ObjSizeCI->isAllOnesValue() || + ObjSizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2))) + return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD); return 0; } @@ -1512,7 +1041,7 @@ struct PrintFOpt : public LibCallOptimization { // in case there is an error writing to stdout. if (FormatStr.size() == 1) { Value *Res = EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context), - FormatStr[0]), B); + FormatStr[0]), B, TD); if (CI->use_empty()) return CI; return B.CreateIntCast(Res, CI->getType(), true); } @@ -1526,7 +1055,7 @@ struct PrintFOpt : public LibCallOptimization { Constant *C = ConstantArray::get(*Context, FormatStr, true); C = new GlobalVariable(*Callee->getParent(), C->getType(), true, GlobalVariable::InternalLinkage, C, "str"); - EmitPutS(C, B); + EmitPutS(C, B, TD); return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), FormatStr.size()+1); } @@ -1535,7 +1064,7 @@ struct PrintFOpt : public LibCallOptimization { // printf("%c", chr) --> putchar(*(i8*)dst) if (FormatStr == "%c" && CI->getNumOperands() > 2 && CI->getOperand(2)->getType()->isIntegerTy()) { - Value *Res = EmitPutChar(CI->getOperand(2), B); + Value *Res = EmitPutChar(CI->getOperand(2), B, TD); if (CI->use_empty()) return CI; return B.CreateIntCast(Res, CI->getType(), true); @@ -1545,7 +1074,7 @@ struct PrintFOpt : public LibCallOptimization { if (FormatStr == "%s\n" && CI->getNumOperands() > 2 && CI->getOperand(2)->getType()->isPointerTy() && CI->use_empty()) { - EmitPutS(CI->getOperand(2), B); + EmitPutS(CI->getOperand(2), B, TD); return CI; } return 0; @@ -1582,8 +1111,8 @@ struct SPrintFOpt : public LibCallOptimization { // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte. - ConstantInt::get - (TD->getIntPtrType(*Context), FormatStr.size()+1),1,B); + ConstantInt::get(TD->getIntPtrType(*Context), + FormatStr.size()+1), 1, B, TD); return ConstantInt::get(CI->getType(), FormatStr.size()); } @@ -1614,11 +1143,11 @@ struct SPrintFOpt : public LibCallOptimization { // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) if (!CI->getOperand(3)->getType()->isPointerTy()) return 0; - Value *Len = EmitStrLen(CI->getOperand(3), B); + Value *Len = EmitStrLen(CI->getOperand(3), B, TD); Value *IncLen = B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1), "leninc"); - EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B); + EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B, TD); // The sprintf result is the unincremented number of bytes in the string. return B.CreateIntCast(Len, CI->getType(), false); @@ -1654,7 +1183,7 @@ struct FWriteOpt : public LibCallOptimization { // If this is writing one byte, turn it into fputc. if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F) Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char"); - EmitFPutC(Char, CI->getOperand(4), B); + EmitFPutC(Char, CI->getOperand(4), B, TD); return ConstantInt::get(CI->getType(), 1); } @@ -1682,7 +1211,7 @@ struct FPutsOpt : public LibCallOptimization { if (!Len) return 0; EmitFWrite(CI->getOperand(1), ConstantInt::get(TD->getIntPtrType(*Context), Len-1), - CI->getOperand(2), B); + CI->getOperand(2), B, TD); return CI; // Known to have no uses (see above). } }; @@ -1716,7 +1245,7 @@ struct FPrintFOpt : public LibCallOptimization { EmitFWrite(CI->getOperand(2), ConstantInt::get(TD->getIntPtrType(*Context), FormatStr.size()), - CI->getOperand(1), B); + CI->getOperand(1), B, TD); return ConstantInt::get(CI->getType(), FormatStr.size()); } @@ -1729,7 +1258,7 @@ struct FPrintFOpt : public LibCallOptimization { if (FormatStr[1] == 'c') { // fprintf(F, "%c", chr) --> *(i8*)dst = chr if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0; - EmitFPutC(CI->getOperand(3), CI->getOperand(1), B); + EmitFPutC(CI->getOperand(3), CI->getOperand(1), B, TD); return ConstantInt::get(CI->getType(), 1); } @@ -1737,7 +1266,7 @@ struct FPrintFOpt : public LibCallOptimization { // fprintf(F, "%s", str) -> fputs(str, F) if (!CI->getOperand(3)->getType()->isPointerTy() || !CI->use_empty()) return 0; - EmitFPutS(CI->getOperand(3), CI->getOperand(1), B); + EmitFPutS(CI->getOperand(3), CI->getOperand(1), B, TD); return CI; } return 0; diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp new file mode 100644 index 0000000..2ea4bb6 --- /dev/null +++ b/lib/Transforms/Utils/BuildLibCalls.cpp @@ -0,0 +1,324 @@ +//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements some functions that will create standard C libcalls. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/BuildLibCalls.h" +#include "llvm/Type.h" +#include "llvm/Constants.h" +#include "llvm/Function.h" +#include "llvm/Module.h" +#include "llvm/Support/IRBuilder.h" +#include "llvm/Target/TargetData.h" +#include "llvm/LLVMContext.h" +#include "llvm/Intrinsics.h" + +using namespace llvm; + +/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. +Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) { + return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr"); +} + +/// EmitStrLen - Emit a call to the strlen function to the builder, for the +/// specified pointer. This always returns an integer value of size intptr_t. +Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[2]; + AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly | + Attribute::NoUnwind); + + LLVMContext &Context = B.GetInsertBlock()->getContext(); + Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2), + TD->getIntPtrType(Context), + B.getInt8PtrTy(), + NULL); + CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen"); + if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +/// EmitStrChr - Emit a call to the strchr function to the builder, for the +/// specified pointer and character. Ptr is required to be some pointer type, +/// and the return value has 'i8*' type. +Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, + const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI = + AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); + + const Type *I8Ptr = B.getInt8PtrTy(); + const Type *I32Ty = B.getInt32Ty(); + Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1), + I8Ptr, I8Ptr, I32Ty, NULL); + CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), + ConstantInt::get(I32Ty, C), "strchr"); + if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + return CI; +} + +/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the +/// specified pointer arguments. +Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, + const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[2]; + AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + const Type *I8Ptr = B.getInt8PtrTy(); + Value *StrCpy = M->getOrInsertFunction("strcpy", AttrListPtr::get(AWI, 2), + I8Ptr, I8Ptr, I8Ptr, NULL); + CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), + "strcpy"); + if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + return CI; +} + +/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always +/// expects that the size has type 'intptr_t' and Dst/Src are pointers. +Value *llvm::EmitMemCpy(Value *Dst, Value *Src, Value *Len, + unsigned Align, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + const Type *Ty = Len->getType(); + Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, &Ty, 1); + Dst = CastToCStr(Dst, B); + Src = CastToCStr(Src, B); + return B.CreateCall4(MemCpy, Dst, Src, Len, + ConstantInt::get(B.getInt32Ty(), Align)); +} + +/// EmitMemMove - Emit a call to the memmove function to the builder. This +/// always expects that the size has type 'intptr_t' and Dst/Src are pointers. +Value *llvm::EmitMemMove(Value *Dst, Value *Src, Value *Len, + unsigned Align, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + const Type *Ty = TD->getIntPtrType(Context); + Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, &Ty, 1); + Dst = CastToCStr(Dst, B); + Src = CastToCStr(Src, B); + Value *A = ConstantInt::get(B.getInt32Ty(), Align); + return B.CreateCall4(MemMove, Dst, Src, Len, A); +} + +/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is +/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. +Value *llvm::EmitMemChr(Value *Ptr, Value *Val, + Value *Len, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI; + AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1), + B.getInt8PtrTy(), + B.getInt8PtrTy(), + B.getInt32Ty(), + TD->getIntPtrType(Context), + NULL); + CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); + + if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +/// EmitMemCmp - Emit a call to the memcmp function. +Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, + Value *Len, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[3]; + AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); + AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly | + Attribute::NoUnwind); + + LLVMContext &Context = B.GetInsertBlock()->getContext(); + Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3), + B.getInt32Ty(), + B.getInt8PtrTy(), + B.getInt8PtrTy(), + TD->getIntPtrType(Context), NULL); + CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), + Len, "memcmp"); + + if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +/// EmitMemSet - Emit a call to the memset function +Value *llvm::EmitMemSet(Value *Dst, Value *Val, + Value *Len, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + Intrinsic::ID IID = Intrinsic::memset; + const Type *Tys[1]; + Tys[0] = Len->getType(); + Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1); + Value *Align = ConstantInt::get(B.getInt32Ty(), 1); + return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align); +} + +/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. +/// 'floor'). This function is known to take a single of type matching 'Op' and +/// returns one value with the same type. If 'Op' is a long double, 'l' is +/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. +Value *llvm::EmitUnaryFloatFnCall(Value *Op, const char *Name, + IRBuilder<> &B, const AttrListPtr &Attrs) { + char NameBuffer[20]; + if (!Op->getType()->isDoubleTy()) { + // If we need to add a suffix, copy into NameBuffer. + unsigned NameLen = strlen(Name); + assert(NameLen < sizeof(NameBuffer)-2); + memcpy(NameBuffer, Name, NameLen); + if (Op->getType()->isFloatTy()) + NameBuffer[NameLen] = 'f'; // floorf + else + NameBuffer[NameLen] = 'l'; // floorl + NameBuffer[NameLen+1] = 0; + Name = NameBuffer; + } + + Module *M = B.GetInsertBlock()->getParent()->getParent(); + Value *Callee = M->getOrInsertFunction(Name, Op->getType(), + Op->getType(), NULL); + CallInst *CI = B.CreateCall(Callee, Op, Name); + CI->setAttributes(Attrs); + if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + + return CI; +} + +/// EmitPutChar - Emit a call to the putchar function. This assumes that Char +/// is an integer. +Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), + B.getInt32Ty(), NULL); + CallInst *CI = B.CreateCall(PutChar, + B.CreateIntCast(Char, + B.getInt32Ty(), + /*isSigned*/true, + "chari"), + "putchar"); + + if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + return CI; +} + +/// EmitPutS - Emit a call to the puts function. This assumes that Str is +/// some pointer. +void llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[2]; + AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + + Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2), + B.getInt32Ty(), + B.getInt8PtrTy(), + NULL); + CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts"); + if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) + CI->setCallingConv(F->getCallingConv()); + +} + +/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is +/// an integer and File is a pointer to FILE. +void llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, + const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[2]; + AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + Constant *F; + if (File->getType()->isPointerTy()) + F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), + B.getInt32Ty(), + B.getInt32Ty(), File->getType(), + NULL); + else + F = M->getOrInsertFunction("fputc", + B.getInt32Ty(), + B.getInt32Ty(), + File->getType(), NULL); + Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, + "chari"); + CallInst *CI = B.CreateCall2(F, Char, File, "fputc"); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); +} + +/// EmitFPutS - Emit a call to the puts function. Str is required to be a +/// pointer and File is a pointer to FILE. +void llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, + const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[3]; + AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); + AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + Constant *F; + if (File->getType()->isPointerTy()) + F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), + B.getInt32Ty(), + B.getInt8PtrTy(), + File->getType(), NULL); + else + F = M->getOrInsertFunction("fputs", B.getInt32Ty(), + B.getInt8PtrTy(), + File->getType(), NULL); + CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs"); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); +} + +/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is +/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. +void llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, + IRBuilder<> &B, const TargetData *TD) { + Module *M = B.GetInsertBlock()->getParent()->getParent(); + AttributeWithIndex AWI[3]; + AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); + AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture); + AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); + LLVMContext &Context = B.GetInsertBlock()->getContext(); + Constant *F; + if (File->getType()->isPointerTy()) + F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3), + TD->getIntPtrType(Context), + B.getInt8PtrTy(), + TD->getIntPtrType(Context), + TD->getIntPtrType(Context), + File->getType(), NULL); + else + F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(Context), + B.getInt8PtrTy(), + TD->getIntPtrType(Context), + TD->getIntPtrType(Context), + File->getType(), NULL); + CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size, + ConstantInt::get(TD->getIntPtrType(Context), 1), File); + + if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) + CI->setCallingConv(Fn->getCallingConv()); +} diff --git a/lib/Transforms/Utils/CMakeLists.txt b/lib/Transforms/Utils/CMakeLists.txt index 93577b4..dec227a 100644 --- a/lib/Transforms/Utils/CMakeLists.txt +++ b/lib/Transforms/Utils/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(LLVMTransformUtils BasicBlockUtils.cpp BasicInliner.cpp BreakCriticalEdges.cpp + BuildLibCalls.cpp CloneFunction.cpp CloneLoop.cpp CloneModule.cpp |