137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===- SymbolRewriter.cpp - Symbol Rewriter ---------------------*- C++ -*-===// 237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The LLVM Compiler Infrastructure 437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source 637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details. 737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolRewriter is a LLVM pass which can rewrite symbols transparently within 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// existing code. It is implemented as a compiler pass and is configured via a 1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// YAML configuration file. 1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The YAML configuration file format is as follows: 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteMapFile := RewriteDescriptors 1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptors := RewriteDescriptor | RewriteDescriptors 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}' 1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields 2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorField := FieldIdentifier ':' FieldValue ',' 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// RewriteDescriptorType := Identifier 2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// FieldIdentifier := Identifier 2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// FieldValue := Identifier 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Identifier := [0-9a-zA-Z]+ 2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Currently, the following descriptor types are supported: 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - function: (function rewriting) 2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Source (original name of the function) 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Target (explicit transformation) 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Transform (pattern transformation) 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Naked (boolean, whether the function is undecorated) 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - global variable: (external linkage global variable rewriting) 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Source (original name of externally visible variable) 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Target (explicit transformation) 3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Transform (pattern transformation) 3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// - global alias: (global alias rewriting) 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Source (original name of the aliased name) 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Target (explicit transformation) 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// + Transform (pattern transformation) 4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Note that source and exactly one of [Target, Transform] must be provided 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// New rewrite descriptors can be created. Addding a new rewrite descriptor 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// involves: 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// a) extended the rewrite descriptor kind enumeration 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// (<anonymous>::RewriteDescriptor::RewriteDescriptorType) 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// b) implementing the new descriptor 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor) 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// c) extending the rewrite map parser 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// (<anonymous>::RewriteMapParser::parseEntry) 5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Specify to rewrite the symbols using the `-rewrite-symbols` option, and 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// specify the map file to use for the rewriting via the `-rewrite-map-file` 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// option. 5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define DEBUG_TYPE "symbol-rewriter" 6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/CodeGen/Passes.h" 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Pass.h" 634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/SmallString.h" 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h" 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/CommandLine.h" 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Debug.h" 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/MemoryBuffer.h" 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Regex.h" 6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/SourceMgr.h" 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/YAMLParser.h" 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/raw_ostream.h" 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Utils/SymbolRewriter.h" 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing namespace llvm; 754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarusing namespace SymbolRewriter; 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::list<std::string> RewriteMapFiles("rewrite-map-file", 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Symbol Rewrite Map"), 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::value_desc("filename")); 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void rewriteComdat(Module &M, GlobalObject *GO, 824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string &Source, 834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string &Target) { 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Comdat *CD = GO->getComdat()) { 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto &Comdats = M.getComdatSymbolTable(); 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Comdat *C = M.getOrInsertComdat(Target); 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines C->setSelectionKind(CD->getSelectionKind()); 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GO->setComdat(C); 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Comdats.erase(Comdats.find(Source)); 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarnamespace { 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType, 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ValueType *(llvm::Module::*Get)(StringRef) const> 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass ExplicitRewriteDescriptor : public RewriteDescriptor { 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string Source; 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string Target; 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked) 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S), 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Target(T) {} 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool performOnModule(Module &M) override; 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static bool classof(const RewriteDescriptor *RD) { 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return RD->getType() == DT; 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType, 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ValueType *(llvm::Module::*Get)(StringRef) const> 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) { 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool Changed = false; 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ValueType *S = (M.*Get)(Source)) { 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (GlobalObject *GO = dyn_cast<GlobalObject>(S)) 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines rewriteComdat(M, GO, Source, Target); 121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Value *T = (M.*Get)(Target)) 12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines S->setValueName(T->getValueName()); 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines S->setName(Target); 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Changed = true; 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Changed; 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType, 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ValueType *(llvm::Module::*Get)(StringRef) const, 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines iterator_range<typename iplist<ValueType>::iterator> 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (llvm::Module::*Iterator)()> 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass PatternRewriteDescriptor : public RewriteDescriptor { 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string Pattern; 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string Transform; 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PatternRewriteDescriptor(StringRef P, StringRef T) 14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : RewriteDescriptor(DT), Pattern(P), Transform(T) { } 14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool performOnModule(Module &M) override; 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static bool classof(const RewriteDescriptor *RD) { 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return RD->getType() == DT; 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <RewriteDescriptor::Type DT, typename ValueType, 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ValueType *(llvm::Module::*Get)(StringRef) const, 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines iterator_range<typename iplist<ValueType>::iterator> 154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (llvm::Module::*Iterator)()> 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>:: 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesperformOnModule(Module &M) { 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool Changed = false; 15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &C : (M.*Iterator)()) { 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Error; 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error); 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Error.empty()) 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines report_fatal_error("unable to transforn " + C.getName() + " in " + 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getModuleIdentifier() + ": " + Error); 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (C.getName() == Name) 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (GlobalObject *GO = dyn_cast<GlobalObject>(&C)) 170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines rewriteComdat(M, GO, C.getName(), Name); 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Value *V = (M.*Get)(Name)) 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines C.setValueName(V->getValueName()); 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines C.setName(Name); 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Changed = true; 17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Changed; 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named (function) symbol. Both the 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// source function name and target function name of the transformation are 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// explicitly spelt out. 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, 18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::Function, &llvm::Module::getFunction> 18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExplicitRewriteFunctionDescriptor; 18837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named (global variable) symbol. Both 19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// the source variable name and target variable name are spelt out. This 19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// applies only to module level variables. 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::GlobalVariable, 19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::getGlobalVariable> 19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExplicitRewriteGlobalVariableDescriptor; 19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for an explicitly named global alias. Both the source 19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// and target name are explicitly spelt out. 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::GlobalAlias, 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::getNamedAlias> 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExplicitRewriteNamedAliasDescriptor; 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for a regular expression based pattern for functions. 20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// A pattern for the function name is provided and a transformation for that 20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// pattern to determine the target function name create the rewrite rule. 20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function, 20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::Function, &llvm::Module::getFunction, 20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::functions> 21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PatternRewriteFunctionDescriptor; 21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Represents a rewrite for a global variable based upon a matching pattern. 21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Each global variable matching the provided pattern will be transformed as 21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// described in the transformation pattern for the target. Applies only to 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// module level variables. 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::GlobalVariable, 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::getGlobalVariable, 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::globals> 22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PatternRewriteGlobalVariableDescriptor; 22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// PatternRewriteNamedAliasDescriptor - represents a rewrite for global 22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// aliases which match a given pattern. The provided transformation will be 22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// applied to each of the matching names. 22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::GlobalAlias, 22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::getNamedAlias, 22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines &llvm::Module::aliases> 22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PatternRewriteNamedAliasDescriptor; 2304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} // namespace 23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parse(const std::string &MapFile, 23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping = 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MemoryBuffer::getFile(MapFile); 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Mapping) 23837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines report_fatal_error("unable to read rewrite map '" + MapFile + "': " + 23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Mapping.getError().message()); 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!parse(*Mapping, DL)) 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines report_fatal_error("unable to parse rewrite map '" + MapFile + "'"); 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile, 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceMgr SM; 25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::Stream YS(MapFile->getBuffer(), SM); 25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Document : YS) { 25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::MappingNode *DescriptorList; 25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // ignore empty documents 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (isa<yaml::NullNode>(Document.getRoot())) 25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot()); 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!DescriptorList) { 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Document.getRoot(), "DescriptorList node must be a map"); 26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Descriptor : *DescriptorList) 26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!parseEntry(YS, Descriptor, DL)) 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry, 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Key; 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::MappingNode *Value; 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> KeyStorage; 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef RewriteType; 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Key = dyn_cast<yaml::ScalarNode>(Entry.getKey()); 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Key) { 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Entry.getKey(), "rewrite type must be a scalar"); 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value = dyn_cast<yaml::MappingNode>(Entry.getValue()); 28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Value) { 28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Entry.getValue(), "rewrite descriptor must be a map"); 28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteType = Key->getValue(KeyStorage); 29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RewriteType.equals("function")) 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return parseRewriteFunctionDescriptor(YS, Key, Value, DL); 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (RewriteType.equals("global variable")) 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL); 29737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (RewriteType.equals("global alias")) 29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL); 29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 30037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Entry.getKey(), "unknown rewrite type"); 30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser:: 30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::MappingNode *Descriptor, 30737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool Naked = false; 30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Source; 31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Target; 31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Transform; 31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Field : *Descriptor) { 31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Key; 31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Value; 31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> KeyStorage; 31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> ValueStorage; 31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef KeyValue; 31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Key) { 32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "descriptor key must be a scalar"); 32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Value) { 32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getValue(), "descriptor value must be a scalar"); 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines KeyValue = Key->getValue(KeyStorage); 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (KeyValue.equals("source")) { 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Error; 33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Source = Value->getValue(ValueStorage); 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Regex(Source).isValid(Error)) { 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "invalid regex: " + Error); 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("target")) { 34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Target = Value->getValue(ValueStorage); 34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("transform")) { 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Transform = Value->getValue(ValueStorage); 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("naked")) { 34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Undecorated; 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Undecorated = Value->getValue(ValueStorage); 34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1"; 35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "unknown key for function"); 35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Transform.empty() == Target.empty()) { 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Descriptor, 35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "exactly one of transform or target must be specified"); 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // TODO see if there is a more elegant solution to selecting the rewrite 36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // descriptor type 36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Target.empty()) 36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked)); 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform)); 36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser:: 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::MappingNode *Descriptor, 37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Source; 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Target; 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Transform; 37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Field : *Descriptor) { 38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Key; 38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Value; 38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> KeyStorage; 38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> ValueStorage; 38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef KeyValue; 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Key) { 38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "descriptor Key must be a scalar"); 39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Value) { 39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getValue(), "descriptor value must be a scalar"); 39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines KeyValue = Key->getValue(KeyStorage); 40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (KeyValue.equals("source")) { 40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Error; 40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Source = Value->getValue(ValueStorage); 40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Regex(Source).isValid(Error)) { 40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "invalid regex: " + Error); 40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("target")) { 40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Target = Value->getValue(ValueStorage); 41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("transform")) { 41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Transform = Value->getValue(ValueStorage); 41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "unknown Key for Global Variable"); 41437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Transform.empty() == Target.empty()) { 41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Descriptor, 42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "exactly one of transform or target must be specified"); 42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Target.empty()) 42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target, 42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*Naked*/false)); 42737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source, 42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Transform)); 43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 43237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 43437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteMapParser:: 43537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesparseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 43637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::MappingNode *Descriptor, 43737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteDescriptorList *DL) { 43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Source; 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Target; 44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Transform; 44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Field : *Descriptor) { 44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Key; 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::ScalarNode *Value; 44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> KeyStorage; 44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<32> ValueStorage; 44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef KeyValue; 44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 45037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Key) { 45137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "descriptor key must be a scalar"); 45237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 45337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Value) { 45737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getValue(), "descriptor value must be a scalar"); 45837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 45937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 46037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 46137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines KeyValue = Key->getValue(KeyStorage); 46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (KeyValue.equals("source")) { 46337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string Error; 46437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 46537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Source = Value->getValue(ValueStorage); 46637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Regex(Source).isValid(Error)) { 46737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "invalid regex: " + Error); 46837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 46937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 47037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("target")) { 47137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Target = Value->getValue(ValueStorage); 47237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (KeyValue.equals("transform")) { 47337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Transform = Value->getValue(ValueStorage); 47437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 47537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Field.getKey(), "unknown key for Global Alias"); 47637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 47737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 47837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 47937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 48037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Transform.empty() == Target.empty()) { 48137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines YS.printError(Descriptor, 48237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "exactly one of transform or target must be specified"); 48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 48437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 48537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 48637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Target.empty()) 48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target, 48837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*Naked*/false)); 48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform)); 49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 49437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace { 49637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass RewriteSymbols : public ModulePass { 49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 49837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static char ID; // Pass identification, replacement for typeid 49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 50037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteSymbols(); 50137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL); 50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 50337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool runOnModule(Module &M) override; 50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 50537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate: 50637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void loadAndParseMapFiles(); 50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SymbolRewriter::RewriteDescriptorList Descriptors; 50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 51037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 51137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineschar RewriteSymbols::ID = 0; 51237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 51337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesRewriteSymbols::RewriteSymbols() : ModulePass(ID) { 51437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry()); 51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines loadAndParseMapFiles(); 51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 51837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesRewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL) 51937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : ModulePass(ID) { 520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Descriptors.splice(Descriptors.begin(), DL); 52137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 52237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 52337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool RewriteSymbols::runOnModule(Module &M) { 52437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool Changed; 52537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Changed = false; 52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Descriptor : Descriptors) 52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Changed |= Descriptor.performOnModule(M); 52937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Changed; 53137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 53237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid RewriteSymbols::loadAndParseMapFiles() { 53437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::vector<std::string> MapFiles(RewriteMapFiles); 53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SymbolRewriter::RewriteMapParser parser; 53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &MapFile : MapFiles) 53837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines parser.parse(MapFile, &Descriptors); 53937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesINITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false, 54337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines false) 54437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 54537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); } 54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesModulePass * 54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesllvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) { 54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return new RewriteSymbols(DL); 55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 551