Skip to content

[NFC] Remove adhoc definition of MDMapT in IRMover #118626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/IR/ValueMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,16 @@ struct ValueMapConfig {
static mutex_type *getMutex(const ExtraDataT &/*Data*/) { return nullptr; }
};

/// This type stores Metadata. Used in ValueMap.
using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;

/// See the file comment.
template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT>>
class ValueMap {
friend class ValueMapCallbackVH<KeyT, ValueT, Config>;

using ValueMapCVH = ValueMapCallbackVH<KeyT, ValueT, Config>;
using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>;
using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;
using ExtraData = typename Config::ExtraData;

MapT Map;
Expand Down
4 changes: 1 addition & 3 deletions llvm/include/llvm/Linker/IRMover.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/IR/ValueMap.h"
#include <functional>

namespace llvm {
Expand Down Expand Up @@ -41,9 +42,6 @@ class IRMover {
static bool isEqual(const StructType *LHS, const StructType *RHS);
};

/// Type of the Metadata map in \a ValueToValueMapTy.
typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;

public:
class IdentifiedStructTypeSet {
// The set of opaque types is the composite module.
Expand Down
53 changes: 40 additions & 13 deletions llvm/include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,27 @@ void CloneFunctionAttributesInto(Function *NewFunc, const Function *OldFunc,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);

/// Clone OldFunc's metadata into NewFunc.
///
/// The caller is expected to populate \p VMap beforehand and set an appropriate
/// \p RemapFlag.
///
/// NOTE: This function doesn't clone !llvm.dbg.cu when cloning into a different
/// module. Use CloneFunctionInto for that behavior.
void CloneFunctionMetadataInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);

/// Clone OldFunc's body into NewFunc.
void CloneFunctionBodyInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
ValueMapTypeRemapper *TypeMapper = nullptr,
ValueMaterializer *Materializer = nullptr);

void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
const Instruction *StartingInst,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
Expand All @@ -202,7 +223,7 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
///
void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, bool ModuleLevelChanges,
SmallVectorImpl<ReturnInst*> &Returns,
SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr);

Expand All @@ -220,6 +241,13 @@ DISubprogram *CollectDebugInfoForCloning(const Function &F,
CloneFunctionChangeType Changes,
DebugInfoFinder &DIFinder);

/// Build a map of debug info to use during Metadata cloning.
/// Returns true if cloning would need module level changes and false if there
/// would only be local changes.
bool BuildDebugInfoMDMap(MDMapT &MD, CloneFunctionChangeType Changes,
DebugInfoFinder &DIFinder,
DISubprogram *SPClonedWithinModule);

/// This class captures the data input to the InlineFunction call, and records
/// the auxiliary results produced by it.
class InlineFunctionInfo {
Expand Down Expand Up @@ -341,32 +369,31 @@ void updateProfileCallee(
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
/// basic blocks and extract their scope. These are candidates for duplication
/// when cloning.
void identifyNoAliasScopesToClone(
ArrayRef<BasicBlock *> BBs, SmallVectorImpl<MDNode *> &NoAliasDeclScopes);
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);
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
/// MDNode onto the cloned scope.
/// Be aware that the cloned scopes are still part of the original scope domain.
void cloneNoAliasScopes(
ArrayRef<MDNode *> NoAliasDeclScopes,
DenseMap<MDNode *, MDNode *> &ClonedScopes,
StringRef Ext, LLVMContext &Context);
void cloneNoAliasScopes(ArrayRef<MDNode *> NoAliasDeclScopes,
DenseMap<MDNode *, MDNode *> &ClonedScopes,
StringRef Ext, LLVMContext &Context);

/// Adapt the metadata for the specified instruction according to the
/// provided mapping. This is normally used after cloning an instruction, when
/// some noalias scopes needed to be cloned.
void adaptNoAliasScopes(
llvm::Instruction *I, const DenseMap<MDNode *, MDNode *> &ClonedScopes,
LLVMContext &Context);
void adaptNoAliasScopes(llvm::Instruction *I,
const DenseMap<MDNode *, MDNode *> &ClonedScopes,
LLVMContext &Context);

/// Clone the specified noalias decl scopes. Then adapt all instructions in the
/// NewBlocks basicblocks to the cloned versions.
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Linker/IRMover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,6 @@ class LocalValueMaterializer final : public ValueMaterializer {
Value *materialize(Value *V) override;
};

/// Type of the Metadata map in \a ValueToValueMapTy.
typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;

/// This is responsible for keeping track of the state used for moving data
/// from SrcM to DstM.
class IRLinker {
Expand Down
209 changes: 120 additions & 89 deletions llvm/lib/Transforms/Utils/CloneFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,119 @@ DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F,
return SPClonedWithinModule;
}

bool llvm::BuildDebugInfoMDMap(MDMapT &MD, CloneFunctionChangeType Changes,
DebugInfoFinder &DIFinder,
DISubprogram *SPClonedWithinModule) {
bool ModuleLevelChanges = Changes > CloneFunctionChangeType::LocalChangesOnly;
if (Changes < CloneFunctionChangeType::DifferentModule &&
DIFinder.subprogram_count() > 0) {
// Turn on module-level changes, since we need to clone (some of) the
// debug info metadata.
//
// FIXME: Metadata effectively owned by a function should be made
// local, and only that local metadata should be cloned.
ModuleLevelChanges = true;

auto mapToSelfIfNew = [&MD](MDNode *N) {
// Avoid clobbering an existing mapping.
(void)MD.try_emplace(N, N);
};

// Avoid cloning types, compile units, and (other) subprograms.
for (DISubprogram *ISP : DIFinder.subprograms()) {
if (ISP != SPClonedWithinModule)
mapToSelfIfNew(ISP);
}

// If a subprogram isn't going to be cloned skip its lexical blocks as well.
for (DIScope *S : DIFinder.scopes()) {
auto *LScope = dyn_cast<DILocalScope>(S);
if (LScope && LScope->getSubprogram() != SPClonedWithinModule)
mapToSelfIfNew(S);
}

for (DICompileUnit *CU : DIFinder.compile_units())
mapToSelfIfNew(CU);

for (DIType *Type : DIFinder.types())
mapToSelfIfNew(Type);
} else {
assert(!SPClonedWithinModule &&
"Subprogram should be in DIFinder->subprogram_count()...");
}

return ModuleLevelChanges;
}

void llvm::CloneFunctionMetadataInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap,
RemapFlags RemapFlag,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
// Duplicate the metadata that is attached to the cloned function.
// Subprograms/CUs/types that were already mapped to themselves won't be
// duplicated.
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
OldFunc->getAllMetadata(MDs);
for (auto MD : MDs) {
NewFunc->addMetadata(MD.first, *MapMetadata(MD.second, VMap, RemapFlag,
TypeMapper, Materializer));
}
}

void llvm::CloneFunctionBodyInto(Function *NewFunc, const Function *OldFunc,
ValueToValueMapTy &VMap, RemapFlags RemapFlag,
SmallVectorImpl<ReturnInst *> &Returns,
const char *NameSuffix,
ClonedCodeInfo *CodeInfo,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) {
if (OldFunc->isDeclaration())
return;

// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
// recursive functions into themselves.
for (const BasicBlock &BB : *OldFunc) {

// Create a new basic block and copy instructions into it!
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);

// Add basic block mapping.
VMap[&BB] = CBB;

// It is only legal to clone a function if a block address within that
// function is never referenced outside of the function. Given that, we
// want to map block addresses from the old function to block addresses in
// the clone. (This is different from the generic ValueMapper
// implementation, which generates an invalid blockaddress when
// cloning a function.)
if (BB.hasAddressTaken()) {
Constant *OldBBAddr = BlockAddress::get(const_cast<Function *>(OldFunc),
const_cast<BasicBlock *>(&BB));
VMap[OldBBAddr] = BlockAddress::get(NewFunc, CBB);
}

// Note return instructions for the caller.
if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
Returns.push_back(RI);
}

// Loop over all of the instructions in the new function, fixing up operand
// references as we go. This uses VMap to do all the hard work.
for (Function::iterator
BB = cast<BasicBlock>(VMap[&OldFunc->front()])->getIterator(),
BE = NewFunc->end();
BB != BE; ++BB)
// Loop over all instructions, fixing each one as we find it, and any
// attached debug-info records.
for (Instruction &II : *BB) {
RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer);
RemapDbgRecordRange(II.getModule(), II.getDbgRecordRange(), VMap,
RemapFlag, TypeMapper, Materializer);
}
}

// Clone OldFunc into NewFunc, transforming the old arguments into references to
// VMap values.
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
Expand Down Expand Up @@ -210,98 +323,16 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
DISubprogram *SPClonedWithinModule =
CollectDebugInfoForCloning(*OldFunc, Changes, DIFinder);

// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
// recursive functions into themselves.
for (const BasicBlock &BB : *OldFunc) {

// Create a new basic block and copy instructions into it!
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);

// Add basic block mapping.
VMap[&BB] = CBB;

// It is only legal to clone a function if a block address within that
// function is never referenced outside of the function. Given that, we
// want to map block addresses from the old function to block addresses in
// the clone. (This is different from the generic ValueMapper
// implementation, which generates an invalid blockaddress when
// cloning a function.)
if (BB.hasAddressTaken()) {
Constant *OldBBAddr = BlockAddress::get(const_cast<Function *>(OldFunc),
const_cast<BasicBlock *>(&BB));
VMap[OldBBAddr] = BlockAddress::get(NewFunc, CBB);
}

// Note return instructions for the caller.
if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
Returns.push_back(RI);
}

if (Changes < CloneFunctionChangeType::DifferentModule &&
DIFinder.subprogram_count() > 0) {
// Turn on module-level changes, since we need to clone (some of) the
// debug info metadata.
//
// FIXME: Metadata effectively owned by a function should be made
// local, and only that local metadata should be cloned.
ModuleLevelChanges = true;

auto mapToSelfIfNew = [&VMap](MDNode *N) {
// Avoid clobbering an existing mapping.
(void)VMap.MD().try_emplace(N, N);
};

// Avoid cloning types, compile units, and (other) subprograms.
SmallPtrSet<const DISubprogram *, 16> MappedToSelfSPs;
for (DISubprogram *ISP : DIFinder.subprograms()) {
if (ISP != SPClonedWithinModule) {
mapToSelfIfNew(ISP);
MappedToSelfSPs.insert(ISP);
}
}

// If a subprogram isn't going to be cloned skip its lexical blocks as well.
for (DIScope *S : DIFinder.scopes()) {
auto *LScope = dyn_cast<DILocalScope>(S);
if (LScope && MappedToSelfSPs.count(LScope->getSubprogram()))
mapToSelfIfNew(S);
}

for (DICompileUnit *CU : DIFinder.compile_units())
mapToSelfIfNew(CU);

for (DIType *Type : DIFinder.types())
mapToSelfIfNew(Type);
} else {
assert(!SPClonedWithinModule &&
"Subprogram should be in DIFinder->subprogram_count()...");
}
ModuleLevelChanges =
BuildDebugInfoMDMap(VMap.MD(), Changes, DIFinder, SPClonedWithinModule);

const auto RemapFlag = ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges;
// Duplicate the metadata that is attached to the cloned function.
// Subprograms/CUs/types that were already mapped to themselves won't be
// duplicated.
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
OldFunc->getAllMetadata(MDs);
for (auto MD : MDs) {
NewFunc->addMetadata(MD.first, *MapMetadata(MD.second, VMap, RemapFlag,
TypeMapper, Materializer));
}

// Loop over all of the instructions in the new function, fixing up operand
// references as we go. This uses VMap to do all the hard work.
for (Function::iterator
BB = cast<BasicBlock>(VMap[&OldFunc->front()])->getIterator(),
BE = NewFunc->end();
BB != BE; ++BB)
// Loop over all instructions, fixing each one as we find it, and any
// attached debug-info records.
for (Instruction &II : *BB) {
RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer);
RemapDbgRecordRange(II.getModule(), II.getDbgRecordRange(), VMap,
RemapFlag, TypeMapper, Materializer);
}
CloneFunctionMetadataInto(NewFunc, OldFunc, VMap, RemapFlag, TypeMapper,
Materializer);

CloneFunctionBodyInto(NewFunc, OldFunc, VMap, RemapFlag, Returns, NameSuffix,
CodeInfo, TypeMapper, Materializer);

// Only update !llvm.dbg.cu for DifferentModule (not CloneModule). In the
// same module, the compile unit will already be listed (or not). When
Expand Down
Loading