summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2014-02-14 22:23:22 +0000
committerQuentin Colombet <qcolombet@apple.com>2014-02-14 22:23:22 +0000
commit038600b42eae3c09fa14c8ab6e4720bcca702dde (patch)
treeb191f3c179b92996886b68adab33bb25cb49d37b /lib/Transforms/Scalar/CodeGenPrepare.cpp
parent5f8059479783315124eca7c406804ae5e7a713fe (diff)
downloadllvm-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.cpp36
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");