[llvm] r252387 - [FunctionAttrs] Add handling for operand bundles
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 6 17:56:00 PST 2015
Author: sanjoy
Date: Fri Nov 6 19:56:00 2015
New Revision: 252387
URL: http://llvm.org/viewvc/llvm-project?rev=252387&view=rev
Log:
[FunctionAttrs] Add handling for operand bundles
Summary:
Teach the FunctionAttrs to do the right thing for IR with operand
bundles.
Reviewers: reames, chandlerc
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D14408
Added:
llvm/trunk/test/Feature/OperandBundles/function-attrs.ll
Modified:
llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=252387&r1=252386&r2=252387&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Fri Nov 6 19:56:00 2015
@@ -328,7 +328,21 @@ struct ArgumentUsesTracker : public Capt
unsigned UseIndex =
std::distance(const_cast<const Use *>(CS.arg_begin()), U);
- assert(UseIndex < CS.arg_size() && "Non-argument use?");
+ assert(UseIndex < CS.data_operands_size() &&
+ "Indirect function calls should have been filtered above!");
+
+ if (UseIndex >= CS.getNumArgOperands()) {
+ // Data operand, but not a argument operand -- must be a bundle operand
+ assert(CS.hasOperandBundles() && "Must be!");
+
+ // CaptureTracking told us that we're being captured by an operand bundle
+ // use. In this case it does not matter if the callee is within our SCC
+ // or not -- we've been captured in some unknown way, and we have to be
+ // conservative.
+ Captured = true;
+ return true;
+ }
+
if (UseIndex >= F->arg_size()) {
assert(F->isVarArg() && "More params than args in non-varargs call");
Captured = true;
@@ -443,14 +457,27 @@ determinePointerReadAttrs(Argument *A,
unsigned UseIndex = std::distance(CS.arg_begin(), U);
- assert(UseIndex < CS.arg_size() && "Non-argument use?");
- if (UseIndex >= F->arg_size()) {
+ assert(UseIndex < CS.data_operands_size() && "Non-argument use?");
+
+ bool IsOperandBundleUse = UseIndex >= CS.getNumArgOperands();
+
+ if (UseIndex >= F->arg_size() && !IsOperandBundleUse) {
assert(F->isVarArg() && "More params than args in non-varargs call");
return Attribute::None;
}
Captures &= !CS.doesNotCapture(UseIndex);
- if (!SCCNodes.count(std::next(F->arg_begin(), UseIndex))) {
+
+ // Since the optimizer (by design) cannot see the data flow corresponding
+ // to a operand bundle use, these cannot participate in the optimistic SCC
+ // analysis. Instead, we model the operand bundle uses as arguments in
+ // call to a function external to the SCC.
+ if (!SCCNodes.count(std::next(F->arg_begin(), UseIndex)) ||
+ IsOperandBundleUse) {
+
+ // The accessors used on CallSite here do the right thing for calls and
+ // invokes with operand bundles.
+
if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(UseIndex))
return Attribute::None;
if (!CS.doesNotAccessMemory(UseIndex))
Added: llvm/trunk/test/Feature/OperandBundles/function-attrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/OperandBundles/function-attrs.ll?rev=252387&view=auto
==============================================================================
--- llvm/trunk/test/Feature/OperandBundles/function-attrs.ll (added)
+++ llvm/trunk/test/Feature/OperandBundles/function-attrs.ll Fri Nov 6 19:56:00 2015
@@ -0,0 +1,24 @@
+; RUN: opt -S -functionattrs < %s | FileCheck %s
+
+declare void @f_readonly() readonly
+declare void @f_readnone() readnone
+
+define void @test_0(i32* %x) {
+; FunctionAttrs must not infer readonly / readnone for %x
+
+; CHECK-LABEL: define void @test_0(i32* %x) {
+ entry:
+ ; CHECK: call void @f_readonly() [ "foo"(i32* %x) ]
+ call void @f_readonly() [ "foo"(i32* %x) ]
+ ret void
+}
+
+define void @test_1(i32* %x) {
+; FunctionAttrs must not infer readonly / readnone for %x
+
+; CHECK-LABEL: define void @test_1(i32* %x) {
+ entry:
+ ; CHECK: call void @f_readnone() [ "foo"(i32* %x) ]
+ call void @f_readnone() [ "foo"(i32* %x) ]
+ ret void
+}
More information about the llvm-commits
mailing list