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 | 038600b42eae3c09fa14c8ab6e4720bcca702dde (patch) | |
tree | b191f3c179b92996886b68adab33bb25cb49d37b /lib/Transforms/Scalar/CodeGenPrepare.cpp | |
parent | 5f8059479783315124eca7c406804ae5e7a713fe (diff) | |
download | llvm-038600b42eae3c09fa14c8ab6e4720bcca702dde.tar.gz llvm-038600b42eae3c09fa14c8ab6e4720bcca702dde.tar.bz2 llvm-038600b42eae3c09fa14c8ab6e4720bcca702dde.tar.xz |
[CodeGenPrepare][AddressingModeMatcher] Give up on type promotion if the
transformation does not bring any immediate benefits and introduce an illegal
operation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201439 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/CodeGenPrepare.cpp')
-rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index 0efeba4af1..0fde256943 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/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"); |