diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -288,12 +288,8 @@ /// themselves as they are either replaced as a whole or not at all. /// /// \param AA The abstract attribute checked. - /// \param WrappedFunctions Functions now enclosed in a shallow wrapper. /// \param DepMap A map from abstract attributes to others they depend on. - /// \param Cache A cache with known results. - bool mayDependOnNonExactDefinition( - AbstractAttribute &AA, SmallPtrSetImpl &WrappedFunctions, - QueryMapTy &DepMap, DenseMap> &Cache); + bool mayDependOnNonExactDefinition(AbstractAttribute &AA, QueryMapTy &DepMap); }; /// Data structure to hold cached (LLVM-IR) information. diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -36,9 +36,7 @@ "Number of function with exact definitions"); STATISTIC(NumFnWithoutExactDefinition, "Number of function without exact definitions"); -STATISTIC(NumFnShallowWrapperCreated, "Number of shallow wrappers created"); -STATISTIC(NumAttrsRequiredDeepWrapper, - "Number of non-trivial attributes requiring a deep wrapper"); +STATISTIC(NumFnWrapperCreated, "Number of wrappers created"); STATISTIC(NumAttributesTimedOut, "Number of abstract attributes timed out before fixpoint"); STATISTIC(NumAttributesValidFixpoint, @@ -736,8 +734,6 @@ << " abstract attributes.\n"; }); - SmallPtrSet WrappedFunctions; - DenseMap> NonExactDefinitionCache; QueryMapTy DepMap; for (auto &It : QueryMap) for (AbstractAttribute *QuerriedAA : It.second) @@ -762,8 +758,7 @@ // We cannot manifest the state if it maybe dependent on non-exact // definitions that could be replaced at link-time. - if (mayDependOnNonExactDefinition(*AA, WrappedFunctions, DepMap, - NonExactDefinitionCache)) + if (mayDependOnNonExactDefinition(*AA, DepMap)) continue; // Manifest the state and record if we changed the IR. @@ -819,9 +814,7 @@ /// return F(arg0, ..., argN); /// } /// -static void createShallowWrapper(Function &F) { - assert(AllowShallowWrappers && - "Cannot create a wrapper if it is not allowed!"); +static void createWrapper(Function &F) { assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!"); Module &M = *F.getParent(); @@ -837,9 +830,6 @@ F.setLinkage(GlobalValue::InternalLinkage); - F.replaceAllUsesWith(Wrapper); - assert(F.getNumUses() == 0 && "Uses remained after wrapper was created!"); - // Move the COMDAT section to the wrapper. // TODO: Check if we need to keep it for F as well. Wrapper->setComdat(F.getComdat()); @@ -866,25 +856,19 @@ CI->setTailCall(true); ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB); - NumFnShallowWrapperCreated++; + NumFnWrapperCreated++; } -bool Attributor::mayDependOnNonExactDefinition( - AbstractAttribute &AA, SmallPtrSetImpl &WrappedFunctions, - QueryMapTy &DepMap, DenseMap> &Cache) { +bool Attributor::mayDependOnNonExactDefinition(AbstractAttribute &AA, + QueryMapTy &DepMap) { Function &AnchorScope = AA.getAnchorScope(); - bool MayDepend = false; - bool NeedShallowWrapper = false; - // Even if this attribute does not depend on another one, we require a shallow + // Even if this attribute does not depend on another one, we require a // wrapper if manifesting it will modify the interface of a non-exact // definition. if (!AnchorScope.hasExactDefinition() && AA.getManifestPosition() != AbstractAttribute::MP_CALL_SITE_ARGUMENT) - NeedShallowWrapper = true; - - // Pre-initialize the cache for recursive dependences. - Cache[&AA] = false; + createWrapper(AnchorScope); auto &SourceAAs = DepMap[&AA]; for (AbstractAttribute *SourceAA : SourceAAs) { @@ -892,56 +876,17 @@ if (SourceAA == &AA || !SourceAA->getState().isValidState()) continue; - // If the anchor scope (=surrounding function) is different and the queried - // abstract attribute is in an non-exact definition the current abstract - // attribute may depend on that non-exact definition. + // If the queried abstract attribute is in an non-exact definition the + // current abstract attribute may depend on that non-exact definition. Function &QuerriedAnchorScope = SourceAA->getAnchorScope(); - if (&QuerriedAnchorScope != &AnchorScope && - (WrappedFunctions.count(&QuerriedAnchorScope) || - !QuerriedAnchorScope.hasExactDefinition())) { - MayDepend = true; - break; - } - - // Check the cache or recurs if necessary to determine if the queried - // abstract attribute might be dependent on non-exact definitions. - Optional QuerriedAARes = Cache[SourceAA]; - if (!QuerriedAARes.hasValue()) - QuerriedAARes = mayDependOnNonExactDefinition(*SourceAA, WrappedFunctions, - DepMap, Cache); - - assert(QuerriedAARes.hasValue()); - if (QuerriedAARes.getValue()) { - MayDepend = true; - break; - } - - // We can depend on call site attributes. Note that we set - // NeedShallowWrapper already in the beginning if this is a function level - // attribute in a non-exact definition. - if (SourceAA->getManifestPosition() == - AbstractAttribute::MP_CALL_SITE_ARGUMENT) + if (QuerriedAnchorScope.hasExactDefinition()) continue; - // A dependence to an abstract attribute in this function was found. This - // means we need to create a shallow wrapper if the function does not have - // an exact definition. - NeedShallowWrapper = !AnchorScope.hasExactDefinition(); - } - - if (NeedShallowWrapper && !AllowShallowWrappers) - MayDepend = true; - - if (!MayDepend && NeedShallowWrapper) { - WrappedFunctions.insert(&AnchorScope); - createShallowWrapper(AnchorScope); + mayDependOnNonExactDefinition(*SourceAA, DepMap); + createWrapper(QuerriedAnchorScope); } - if (MayDepend) - NumAttrsRequiredDeepWrapper++; - - Cache[&AA] = MayDepend; - return MayDepend; + return false; } void Attributor::identifyDefaultAbstractAttributes(