#define DEBUG_TYPE "symbol-rewriter"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Pass.h"
-#include "llvm/PassManager.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
using namespace llvm;
+using namespace SymbolRewriter;
static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
cl::desc("Symbol Rewrite Map"),
cl::value_desc("filename"));
-namespace llvm {
-namespace SymbolRewriter {
+static void rewriteComdat(Module &M, GlobalObject *GO,
+ const std::string &Source,
+ const std::string &Target) {
+ if (Comdat *CD = GO->getComdat()) {
+ auto &Comdats = M.getComdatSymbolTable();
+
+ Comdat *C = M.getOrInsertComdat(Target);
+ C->setSelectionKind(CD->getSelectionKind());
+ GO->setComdat(C);
+
+ Comdats.erase(Comdats.find(Source));
+ }
+}
+
+namespace {
template <RewriteDescriptor::Type DT, typename ValueType,
ValueType *(llvm::Module::*Get)(StringRef) const>
class ExplicitRewriteDescriptor : public RewriteDescriptor {
bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {
bool Changed = false;
if (ValueType *S = (M.*Get)(Source)) {
+ if (GlobalObject *GO = dyn_cast<GlobalObject>(S))
+ rewriteComdat(M, GO, Source, Target);
+
if (Value *T = (M.*Get)(Target))
S->setValueName(T->getValueName());
else
S->setName(Target);
+
Changed = true;
}
return Changed;
template <RewriteDescriptor::Type DT, typename ValueType,
ValueType *(llvm::Module::*Get)(StringRef) const,
- iterator_range<typename iplist<ValueType>::iterator> (llvm::Module::*Iterator)()>
+ iterator_range<typename iplist<ValueType>::iterator>
+ (llvm::Module::*Iterator)()>
class PatternRewriteDescriptor : public RewriteDescriptor {
public:
const std::string Pattern;
template <RewriteDescriptor::Type DT, typename ValueType,
ValueType *(llvm::Module::*Get)(StringRef) const,
- iterator_range<typename iplist<ValueType>::iterator> (llvm::Module::*Iterator)()>
+ iterator_range<typename iplist<ValueType>::iterator>
+ (llvm::Module::*Iterator)()>
bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::
performOnModule(Module &M) {
bool Changed = false;
report_fatal_error("unable to transforn " + C.getName() + " in " +
M.getModuleIdentifier() + ": " + Error);
+ if (C.getName() == Name)
+ continue;
+
+ if (GlobalObject *GO = dyn_cast<GlobalObject>(&C))
+ rewriteComdat(M, GO, C.getName(), Name);
+
if (Value *V = (M.*Get)(Name))
C.setValueName(V->getValueName());
else
/// Represents a rewrite for an explicitly named (function) symbol. Both the
/// source function name and target function name of the transformation are
/// explicitly spelt out.
-using ExplicitRewriteFunctionDescriptor =
- ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, llvm::Function,
- &llvm::Module::getFunction>;
+typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function,
+ llvm::Function, &llvm::Module::getFunction>
+ ExplicitRewriteFunctionDescriptor;
/// Represents a rewrite for an explicitly named (global variable) symbol. Both
/// the source variable name and target variable name are spelt out. This
/// applies only to module level variables.
-using ExplicitRewriteGlobalVariableDescriptor =
- ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
- llvm::GlobalVariable,
- &llvm::Module::getGlobalVariable>;
+typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
+ llvm::GlobalVariable,
+ &llvm::Module::getGlobalVariable>
+ ExplicitRewriteGlobalVariableDescriptor;
/// Represents a rewrite for an explicitly named global alias. Both the source
/// and target name are explicitly spelt out.
-using ExplicitRewriteNamedAliasDescriptor =
- ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
- llvm::GlobalAlias, &llvm::Module::getNamedAlias>;
+typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
+ llvm::GlobalAlias,
+ &llvm::Module::getNamedAlias>
+ ExplicitRewriteNamedAliasDescriptor;
/// Represents a rewrite for a regular expression based pattern for functions.
/// A pattern for the function name is provided and a transformation for that
/// pattern to determine the target function name create the rewrite rule.
-using PatternRewriteFunctionDescriptor =
- PatternRewriteDescriptor<RewriteDescriptor::Type::Function, llvm::Function,
- &llvm::Module::getFunction,
- &llvm::Module::functions>;
-
+typedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function,
+ llvm::Function, &llvm::Module::getFunction,
+ &llvm::Module::functions>
+ PatternRewriteFunctionDescriptor;
/// Represents a rewrite for a global variable based upon a matching pattern.
/// Each global variable matching the provided pattern will be transformed as
/// described in the transformation pattern for the target. Applies only to
/// module level variables.
-using PatternRewriteGlobalVariableDescriptor =
- PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
- llvm::GlobalVariable,
- &llvm::Module::getGlobalVariable,
- &llvm::Module::globals>;
+typedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,
+ llvm::GlobalVariable,
+ &llvm::Module::getGlobalVariable,
+ &llvm::Module::globals>
+ PatternRewriteGlobalVariableDescriptor;
/// PatternRewriteNamedAliasDescriptor - represents a rewrite for global
/// aliases which match a given pattern. The provided transformation will be
/// applied to each of the matching names.
-using PatternRewriteNamedAliasDescriptor =
- PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
- llvm::GlobalAlias,
- &llvm::Module::getNamedAlias,
- &llvm::Module::aliases>;
-
+typedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias,
+ llvm::GlobalAlias,
+ &llvm::Module::getNamedAlias,
+ &llvm::Module::aliases>
+ PatternRewriteNamedAliasDescriptor;
+} // namespace
bool RewriteMapParser::parse(const std::string &MapFile,
RewriteDescriptorList *DL) {
bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,
RewriteDescriptorList *DL) {
- const std::string kRewriteTypeFunction = "function";
- const std::string kRewriteTypeGlobalVariable = "global variable";
- const std::string kRewriteTypeGlobalAlias = "global alias";
-
yaml::ScalarNode *Key;
yaml::MappingNode *Value;
SmallString<32> KeyStorage;
}
RewriteType = Key->getValue(KeyStorage);
- if (RewriteType == kRewriteTypeFunction)
+ if (RewriteType.equals("function"))
return parseRewriteFunctionDescriptor(YS, Key, Value, DL);
- else if (RewriteType == kRewriteTypeGlobalVariable)
+ else if (RewriteType.equals("global variable"))
return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);
- else if (RewriteType == kRewriteTypeGlobalAlias)
+ else if (RewriteType.equals("global alias"))
return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);
YS.printError(Entry.getKey(), "unknown rewrite type");
parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
yaml::MappingNode *Descriptor,
RewriteDescriptorList *DL) {
- const std::string kDescriptorFieldSource = "source";
- const std::string kDescriptorFieldTarget = "target";
- const std::string kDescriptorFieldTransform = "transform";
- const std::string kDescriptorFieldNaked = "naked";
-
bool Naked = false;
std::string Source;
std::string Target;
}
KeyValue = Key->getValue(KeyStorage);
- if (KeyValue == kDescriptorFieldSource) {
+ if (KeyValue.equals("source")) {
std::string Error;
Source = Value->getValue(ValueStorage);
YS.printError(Field.getKey(), "invalid regex: " + Error);
return false;
}
- } else if (KeyValue == kDescriptorFieldTarget) {
+ } else if (KeyValue.equals("target")) {
Target = Value->getValue(ValueStorage);
- } else if (KeyValue == kDescriptorFieldTransform) {
+ } else if (KeyValue.equals("transform")) {
Transform = Value->getValue(ValueStorage);
- } else if (KeyValue == kDescriptorFieldNaked) {
+ } else if (KeyValue.equals("naked")) {
std::string Undecorated;
Undecorated = Value->getValue(ValueStorage);
parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
yaml::MappingNode *Descriptor,
RewriteDescriptorList *DL) {
- const std::string kDescriptorFieldSource = "source";
- const std::string kDescriptorFieldTarget = "target";
- const std::string kDescriptorFieldTransform = "transform";
-
std::string Source;
std::string Target;
std::string Transform;
}
KeyValue = Key->getValue(KeyStorage);
- if (KeyValue == kDescriptorFieldSource) {
+ if (KeyValue.equals("source")) {
std::string Error;
Source = Value->getValue(ValueStorage);
YS.printError(Field.getKey(), "invalid regex: " + Error);
return false;
}
- } else if (KeyValue == kDescriptorFieldTarget) {
+ } else if (KeyValue.equals("target")) {
Target = Value->getValue(ValueStorage);
- } else if (KeyValue == kDescriptorFieldTransform) {
+ } else if (KeyValue.equals("transform")) {
Transform = Value->getValue(ValueStorage);
} else {
YS.printError(Field.getKey(), "unknown Key for Global Variable");
parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
yaml::MappingNode *Descriptor,
RewriteDescriptorList *DL) {
- const std::string kDescriptorFieldSource = "source";
- const std::string kDescriptorFieldTarget = "target";
- const std::string kDescriptorFieldTransform = "transform";
-
std::string Source;
std::string Target;
std::string Transform;
}
KeyValue = Key->getValue(KeyStorage);
- if (KeyValue == kDescriptorFieldSource) {
+ if (KeyValue.equals("source")) {
std::string Error;
Source = Value->getValue(ValueStorage);
YS.printError(Field.getKey(), "invalid regex: " + Error);
return false;
}
- } else if (KeyValue == kDescriptorFieldTarget) {
+ } else if (KeyValue.equals("target")) {
Target = Value->getValue(ValueStorage);
- } else if (KeyValue == kDescriptorFieldTransform) {
+ } else if (KeyValue.equals("transform")) {
Transform = Value->getValue(ValueStorage);
} else {
YS.printError(Field.getKey(), "unknown key for Global Alias");
return true;
}
-}
-}
namespace {
class RewriteSymbols : public ModulePass {
RewriteSymbols();
RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL);
- virtual bool runOnModule(Module &M) override;
+ bool runOnModule(Module &M) override;
private:
void loadAndParseMapFiles();
RewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL)
: ModulePass(ID) {
- std::swap(Descriptors, DL);
+ Descriptors.splice(Descriptors.begin(), DL);
}
bool RewriteSymbols::runOnModule(Module &M) {
}
INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false,
- false);
+ false)
ModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); }