diff options
author | Quentin Colombet <qcolombet@apple.com> | 2014-02-14 22:23:22 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2014-02-14 22:23:22 +0000 |
commit | 867c550947e941d99ffb7b9485f14c787942e7d5 (patch) | |
tree | e1e147dc1049386aab380eaf4192bc9929309ab2 /llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp | |
parent | 2add1146005099d23d29e42a44058cc703cd381e (diff) | |
download | bcm5719-llvm-867c550947e941d99ffb7b9485f14c787942e7d5.tar.gz bcm5719-llvm-867c550947e941d99ffb7b9485f14c787942e7d5.zip |
[CodeGenPrepare][AddressingModeMatcher] Give up on type promotion if the
transformation does not bring any immediate benefits and introduce an illegal
operation.
llvm-svn: 201439
Diffstat (limited to 'llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp index 0efeba4af1c..0fde256943d 100644 --- a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -1376,6 +1376,8 @@ private: ExtAddrMode &AMBefore, ExtAddrMode &AMAfter); bool ValueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2); + bool IsPromotionProfitable(unsigned MatchedSize, unsigned SizeWithPromotion, + Value *PromotedOperand) const; }; /// MatchScaledValue - Try adding ScaleReg*Scale to the current addressing mode. @@ -1728,6 +1730,35 @@ TypePromotionHelper::promoteOperandForOther(Instruction *SExt, return SExtOpnd; } +/// IsPromotionProfitable - Check whether or not promoting an instruction +/// to a wider type was profitable. +/// \p MatchedSize gives the number of instructions that have been matched +/// in the addressing mode after the promotion was applied. +/// \p SizeWithPromotion gives the number of created instructions for +/// the promotion plus the number of instructions that have been +/// matched in the addressing mode before the promotion. +/// \p PromotedOperand is the value that has been promoted. +/// \return True if the promotion is profitable, false otherwise. +bool +AddressingModeMatcher::IsPromotionProfitable(unsigned MatchedSize, + unsigned SizeWithPromotion, + Value *PromotedOperand) const { + // We folded less instructions than what we created to promote the operand. + // This is not profitable. + if (MatchedSize < SizeWithPromotion) + return false; + if (MatchedSize > SizeWithPromotion) + return true; + // The promotion is neutral but it may help folding the sign extension in + // loads for instance. + // Check that we did not create an illegal instruction. + Instruction *PromotedInst = dyn_cast<Instruction>(PromotedOperand); + if (!PromotedInst) + return false; + return TLI.isOperationLegalOrCustom(PromotedInst->getOpcode(), + EVT::getEVT(PromotedInst->getType())); +} + /// MatchOperationAddr - Given an instruction or constant expr, see if we can /// fold the operation into the addressing mode. If so, update the addressing /// mode and return true, otherwise return false without modifying AddrMode. @@ -1935,9 +1966,8 @@ bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode, unsigned OldSize = AddrModeInsts.size(); if (!MatchAddr(PromotedOperand, Depth) || - // We fold less instructions than what we created. - // Undo at this point. - (OldSize + CreatedInsts > AddrModeInsts.size())) { + !IsPromotionProfitable(AddrModeInsts.size(), OldSize + CreatedInsts, + PromotedOperand)) { AddrMode = BackupAddrMode; AddrModeInsts.resize(OldSize); DEBUG(dbgs() << "Sign extension does not pay off: rollback\n"); |