diff options
author | Dan Gohman <dan433584@gmail.com> | 2017-11-08 21:59:51 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2017-11-08 21:59:51 +0000 |
commit | 2c74fe977daf8d1d4c8b64cdd6d3a9999a4b4655 (patch) | |
tree | 98b7ec31ec1bfdcc6869e3d884d44bc273bde172 /llvm/lib/Analysis | |
parent | c707c6f3a70f18ef8ceb1badea1de9965ce97e06 (diff) | |
download | bcm5719-llvm-2c74fe977daf8d1d4c8b64cdd6d3a9999a4b4655.tar.gz bcm5719-llvm-2c74fe977daf8d1d4c8b64cdd6d3a9999a4b4655.zip |
Add an @llvm.sideeffect intrinsic
This patch implements Chandler's idea [0] for supporting languages that
require support for infinite loops with side effects, such as Rust, providing
part of a solution to bug 965 [1].
Specifically, it adds an `llvm.sideeffect()` intrinsic, which has no actual
effect, but which appears to optimization passes to have obscure side effects,
such that they don't optimize away loops containing it. It also teaches
several optimization passes to ignore this intrinsic, so that it doesn't
significantly impact optimization in most cases.
As discussed on llvm-dev [2], this patch is the first of two major parts.
The second part, to change LLVM's semantics to have defined behavior
on infinite loops by default, with a function attribute for opting into
potential-undefined-behavior, will be implemented and posted for review in
a separate patch.
[0] http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html
[1] https://bugs.llvm.org/show_bug.cgi?id=965
[2] http://lists.llvm.org/pipermail/llvm-dev/2017-October/118632.html
Differential Revision: https://reviews.llvm.org/D38336
llvm-svn: 317729
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/AliasSetTracker.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Analysis/VectorUtils.cpp | 3 |
3 files changed, 6 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp index 025e8119deb..b575944092a 100644 --- a/llvm/lib/Analysis/AliasSetTracker.cpp +++ b/llvm/lib/Analysis/AliasSetTracker.cpp @@ -436,6 +436,7 @@ void AliasSetTracker::addUnknown(Instruction *Inst) { break; // FIXME: Add lifetime/invariant intrinsics (See: PR30807). case Intrinsic::assume: + case Intrinsic::sideeffect: return; } } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 2010858139a..9a0df74fd57 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -433,6 +433,7 @@ static bool isAssumeLikeIntrinsic(const Instruction *I) { default: break; // FIXME: This list is repeated from NoTTI::getIntrinsicCost. case Intrinsic::assume: + case Intrinsic::sideeffect: case Intrinsic::dbg_declare: case Intrinsic::dbg_value: case Intrinsic::invariant_start: @@ -3857,7 +3858,8 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) { // FIXME: This isn't aggressive enough; a call which only writes to a global // is guaranteed to return. return CS.onlyReadsMemory() || CS.onlyAccessesArgMemory() || - match(I, m_Intrinsic<Intrinsic::assume>()); + match(I, m_Intrinsic<Intrinsic::assume>()) || + match(I, m_Intrinsic<Intrinsic::sideeffect>()); } // Other instructions return normally. diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp index 554d132c2ab..2becfbfe8a8 100644 --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -91,7 +91,8 @@ Intrinsic::ID llvm::getVectorIntrinsicIDForCall(const CallInst *CI, return Intrinsic::not_intrinsic; if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start || - ID == Intrinsic::lifetime_end || ID == Intrinsic::assume) + ID == Intrinsic::lifetime_end || ID == Intrinsic::assume || + ID == Intrinsic::sideeffect) return ID; return Intrinsic::not_intrinsic; } |