X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FFunctionAttrs.cpp;fp=lib%2FTransforms%2FIPO%2FFunctionAttrs.cpp;h=b63ffb4a72cab791f9f13246eaa0931c8cfebea9;hp=6024137bfe348a3ce1834854be71c4dfb7c3399f;hb=e70403f1977ee7c22814d8a45aff0bb39f95a194;hpb=d044355f2d319b2003186187aabe2d0ed6e63684 diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index 6024137bfe3..b63ffb4a72c 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -328,7 +328,21 @@ struct ArgumentUsesTracker : public CaptureTracker { unsigned UseIndex = std::distance(const_cast(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))