84using namespace SymbolRewriter;
86#define DEBUG_TYPE "symbol-rewriter"
94 const std::string &Source,
95 const std::string &
Target) {
97 auto &Comdats = M.getComdatSymbolTable();
100 C->setSelectionKind(CD->getSelectionKind());
103 Comdats.erase(Comdats.find(Source));
132bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(
Module &M) {
133 bool Changed =
false;
139 S->setValueName(
T->getValueName());
157 const std::string Transform;
176bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
177performOnModule(
Module &M) {
178 bool Changed =
false;
179 for (
auto &
C : (
M.*Iterator)()) {
185 M.getModuleIdentifier() +
": " +
Error);
187 if (
C.getName() ==
Name)
194 C.setValueName(
V->getValueName());
208using ExplicitRewriteFunctionDescriptor =
209 ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function,
Function,
215using ExplicitRewriteGlobalVariableDescriptor =
216 ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
221using ExplicitRewriteNamedAliasDescriptor =
222 ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
GlobalAlias,
228using PatternRewriteFunctionDescriptor =
229 PatternRewriteDescriptor<RewriteDescriptor::Type::Function,
Function,
236using PatternRewriteGlobalVariableDescriptor =
237 PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
244using PatternRewriteNamedAliasDescriptor =
245 PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
GlobalAlias,
257 "': " + Mapping.
getError().message());
270 for (
auto &Document : YS) {
274 if (isa<yaml::NullNode>(Document.getRoot()))
277 DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot());
278 if (!DescriptorList) {
279 YS.printError(Document.getRoot(),
"DescriptorList node must be a map");
283 for (
auto &Descriptor : *DescriptorList)
284 if (!parseEntry(YS, Descriptor,
DL))
298 Key = dyn_cast<yaml::ScalarNode>(
Entry.getKey());
304 Value = dyn_cast<yaml::MappingNode>(
Entry.getValue());
310 RewriteType =
Key->getValue(KeyStorage);
311 if (RewriteType ==
"function")
312 return parseRewriteFunctionDescriptor(YS, Key,
Value,
DL);
313 else if (RewriteType ==
"global variable")
314 return parseRewriteGlobalVariableDescriptor(YS, Key,
Value,
DL);
315 else if (RewriteType ==
"global alias")
316 return parseRewriteGlobalAliasDescriptor(YS, Key,
Value,
DL);
322bool RewriteMapParser::
329 std::string Transform;
331 for (
auto &
Field : *Descriptor) {
338 Key = dyn_cast<yaml::ScalarNode>(
Field.getKey());
344 Value = dyn_cast<yaml::ScalarNode>(
Field.getValue());
350 KeyValue =
Key->getValue(KeyStorage);
351 if (KeyValue ==
"source") {
354 Source = std::string(
Value->getValue(ValueStorage));
359 }
else if (KeyValue ==
"target") {
360 Target = std::string(
Value->getValue(ValueStorage));
361 }
else if (KeyValue ==
"transform") {
362 Transform = std::string(
Value->getValue(ValueStorage));
363 }
else if (KeyValue ==
"naked") {
364 std::string Undecorated;
366 Undecorated = std::string(
Value->getValue(ValueStorage));
374 if (Transform.empty() ==
Target.empty()) {
376 "exactly one of transform or target must be specified");
383 DL->
push_back(std::make_unique<ExplicitRewriteFunctionDescriptor>(
387 std::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
392bool RewriteMapParser::
398 std::string Transform;
400 for (
auto &
Field : *Descriptor) {
407 Key = dyn_cast<yaml::ScalarNode>(
Field.getKey());
413 Value = dyn_cast<yaml::ScalarNode>(
Field.getValue());
419 KeyValue =
Key->getValue(KeyStorage);
420 if (KeyValue ==
"source") {
423 Source = std::string(
Value->getValue(ValueStorage));
428 }
else if (KeyValue ==
"target") {
429 Target = std::string(
Value->getValue(ValueStorage));
430 }
else if (KeyValue ==
"transform") {
431 Transform = std::string(
Value->getValue(ValueStorage));
438 if (Transform.empty() ==
Target.empty()) {
440 "exactly one of transform or target must be specified");
445 DL->
push_back(std::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
449 DL->
push_back(std::make_unique<PatternRewriteGlobalVariableDescriptor>(
455bool RewriteMapParser::
461 std::string Transform;
463 for (
auto &
Field : *Descriptor) {
470 Key = dyn_cast<yaml::ScalarNode>(
Field.getKey());
476 Value = dyn_cast<yaml::ScalarNode>(
Field.getValue());
482 KeyValue =
Key->getValue(KeyStorage);
483 if (KeyValue ==
"source") {
486 Source = std::string(
Value->getValue(ValueStorage));
491 }
else if (KeyValue ==
"target") {
492 Target = std::string(
Value->getValue(ValueStorage));
493 }
else if (KeyValue ==
"transform") {
494 Transform = std::string(
Value->getValue(ValueStorage));
501 if (Transform.empty() ==
Target.empty()) {
503 "exactly one of transform or target must be specified");
508 DL->
push_back(std::make_unique<ExplicitRewriteNamedAliasDescriptor>(
512 DL->
push_back(std::make_unique<PatternRewriteNamedAliasDescriptor>(
529 for (
auto &Descriptor : Descriptors)
530 Changed |= Descriptor->performOnModule(M);
535void RewriteSymbolPass::loadAndParseMapFiles() {
539 for (
const auto &MapFile : MapFiles)
540 Parser.
parse(MapFile, &Descriptors);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Provides ErrorOr<T> smart pointer.
static bool runImpl(Function &F, const TargetLowering &TLI)
Module.h This file contains the declarations for the Module class.
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallString class.
static cl::list< std::string > RewriteMapFiles("rewrite-map-file", cl::desc("Symbol Rewrite Map"), cl::value_desc("filename"), cl::Hidden)
static void rewriteComdat(Module &M, GlobalObject *GO, const std::string &Source, const std::string &Target)
A container for analyses that lazily runs them and caches their results.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
void setComdat(Comdat *C)
const Comdat * getComdat() const
void push_back(MachineInstr *MI)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
A Module instance is used to store all the information related to an LLVM module.
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
iterator_range< iterator > functions()
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
GlobalVariable * getGlobalVariable(StringRef Name) const
Look up the specified global variable in the module symbol table.
GlobalAlias * getNamedAlias(StringRef Name) const
Return the global alias in the module with the specified name, of arbitrary type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
std::string sub(StringRef Repl, StringRef String, std::string *Error=nullptr) const
sub - Return the result of replacing the first match of the regex in String with the Repl string.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
StringRef - Represent a constant reference to a string, i.e.
std::string lower() const
The basic entity representing a rewrite operation.
virtual bool performOnModule(Module &M)=0
bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors)
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
A range adaptor for a pair of iterators.
Represents a YAML map created from either a block map for a flow map.
A scalar node is an opaque datum that can be presented as a series of zero or more Unicode scalar val...
This class represents a YAML stream potentially containing multiple documents.
void printError(Node *N, const Twine &Msg, SourceMgr::DiagKind Kind=SourceMgr::DK_Error)
This file defines classes to implement an intrusive doubly linked list class (i.e.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
@ C
The default llvm calling convention, compatible with C.
std::list< std::unique_ptr< RewriteDescriptor > > RewriteDescriptorList
This is an optimization pass for GlobalISel generic memory operations.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
Implement std::hash so that hash_code can be used in STL containers.