aboutsummaryrefslogtreecommitdiff
path: root/llvm/include/llvm/Transforms/Utils/Cloning.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/Transforms/Utils/Cloning.h')
-rw-r--r--llvm/include/llvm/Transforms/Utils/Cloning.h61
1 files changed, 51 insertions, 10 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 56aaa5d48e2a..f4fb265c25e0 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -75,7 +75,16 @@ struct ClonedCodeInfo {
/// originally inserted callsites were DCE'ed after they were cloned.
std::vector<WeakTrackingVH> OperandBundleCallSites;
+ /// Like VMap, but maps only unsimplified instructions. Values in the map
+ /// may be dangling, it is only intended to be used via isSimplified(), to
+ /// check whether the main VMap mapping involves simplification or not.
+ DenseMap<const Value *, const Value *> OrigVMap;
+
ClonedCodeInfo() = default;
+
+ bool isSimplified(const Value *From, const Value *To) const {
+ return OrigVMap.lookup(From) != To;
+ }
};
/// Return a copy of the specified basic block, but without
@@ -119,24 +128,45 @@ BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
/// values. The final argument captures information about the cloned code if
/// non-null.
///
-/// VMap contains no non-identity GlobalValue mappings and debug info metadata
-/// will not be cloned.
+/// \pre VMap contains no non-identity GlobalValue mappings.
///
Function *CloneFunction(Function *F, ValueToValueMapTy &VMap,
ClonedCodeInfo *CodeInfo = nullptr);
+enum class CloneFunctionChangeType {
+ LocalChangesOnly,
+ GlobalChanges,
+ DifferentModule,
+ ClonedModule,
+};
+
/// Clone OldFunc into NewFunc, transforming the old arguments into references
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
/// cloned into it will be added to the end of the function. This function
/// fills in a list of return instructions, and can optionally remap types
/// and/or append the specified suffix to all values cloned.
///
-/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
-/// mappings.
+/// If \p Changes is \a CloneFunctionChangeType::LocalChangesOnly, VMap is
+/// required to contain no non-identity GlobalValue mappings. Otherwise,
+/// referenced metadata will be cloned.
///
+/// If \p Changes is less than \a CloneFunctionChangeType::DifferentModule
+/// indicating cloning into the same module (even if it's LocalChangesOnly), if
+/// debug info metadata transitively references a \a DISubprogram, it will be
+/// cloned, effectively upgrading \p Changes to GlobalChanges while suppressing
+/// cloning of types and compile units.
+///
+/// If \p Changes is \a CloneFunctionChangeType::DifferentModule, the new
+/// module's \c !llvm.dbg.cu will get updated with any newly created compile
+/// units. (\a CloneFunctionChangeType::ClonedModule leaves that work for the
+/// caller.)
+///
+/// FIXME: Consider simplifying this function by splitting out \a
+/// CloneFunctionMetadataInto() and expecting / updating callers to call it
+/// first when / how it's needed.
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
- ValueToValueMapTy &VMap, bool ModuleLevelChanges,
- SmallVectorImpl<ReturnInst*> &Returns,
+ ValueToValueMapTy &VMap, CloneFunctionChangeType Changes,
+ SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
ValueMapTypeRemapper *TypeMapper = nullptr,
@@ -164,8 +194,7 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
- ClonedCodeInfo *CodeInfo = nullptr,
- Instruction *TheCall = nullptr);
+ ClonedCodeInfo *CodeInfo = nullptr);
/// This class captures the data input to the InlineFunction call, and records
/// the auxiliary results produced by it.
@@ -176,9 +205,10 @@ public:
function_ref<AssumptionCache &(Function &)> GetAssumptionCache = nullptr,
ProfileSummaryInfo *PSI = nullptr,
BlockFrequencyInfo *CallerBFI = nullptr,
- BlockFrequencyInfo *CalleeBFI = nullptr)
+ BlockFrequencyInfo *CalleeBFI = nullptr, bool UpdateProfile = true)
: CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI),
- CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {}
+ CallerBFI(CallerBFI), CalleeBFI(CalleeBFI),
+ UpdateProfile(UpdateProfile) {}
/// If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
@@ -202,6 +232,10 @@ public:
/// `InlinedCalls` above is used.
SmallVector<CallBase *, 8> InlinedCallSites;
+ /// Update profile for callee as well as cloned version. We need to do this
+ /// for regular inlining, but not for inlining from sample profile loader.
+ bool UpdateProfile;
+
void reset() {
StaticAllocas.clear();
InlinedCalls.clear();
@@ -274,6 +308,13 @@ void updateProfileCallee(
void identifyNoAliasScopesToClone(
ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
+/// instruction range and extract their scope. These are candidates for
+/// duplication when cloning.
+void identifyNoAliasScopesToClone(
+ BasicBlock::iterator Start, BasicBlock::iterator End,
+ SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
+
/// Duplicate the specified list of noalias decl scopes.
/// The 'Ext' string is added as an extension to the name.
/// Afterwards, the ClonedScopes contains the mapping of the original scope