示例#1
0
llvm::GlobalVariable* JitCodeSpecializer::_clone_global_variable(SpecializationContext& context,
                                                                 const llvm::GlobalVariable& global_variable) const {
  // If the global variable already exists in the module, there is no point in cloning it again
  if (auto global = context.module->getGlobalVariable(global_variable.getName())) {
    return global;
  }

  // Create a new global variable with the same type, attributes, and properties
  const auto cloned_global = llvm::dyn_cast<llvm::GlobalVariable>(
      context.module->getOrInsertGlobal(global_variable.getName(), global_variable.getValueType()));
  cloned_global->setLinkage(global_variable.getLinkage());
  cloned_global->setThreadLocalMode(global_variable.getThreadLocalMode());
  cloned_global->copyAttributesFrom(&global_variable);

  if (!global_variable.isDeclaration()) {
    if (global_variable.hasInitializer()) {
      // Instruct LLVM to perform the cloning of the actual value (i.e., initializer) of the variable
      cloned_global->setInitializer(llvm::MapValue(global_variable.getInitializer(), context.llvm_value_map));
    }

    // Clone LLVM metadata for the global variable
    llvm::SmallVector<std::pair<uint32_t, llvm::MDNode*>, 1> metadata_nodes;
    global_variable.getAllMetadata(metadata_nodes);
    for (const auto& metadata_node : metadata_nodes) {
      cloned_global->addMetadata(metadata_node.first,
                                 *MapMetadata(metadata_node.second, context.llvm_value_map, llvm::RF_MoveDistinctMDs));
    }
  }

  return cloned_global;
}
示例#2
0
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
                              ValueToValueMapTy &VMap) {
  auto *MFs = Src.getModuleFlagsMetadata();
  if (!MFs)
    return;
  for (auto *MF : MFs->operands())
    Dst.addModuleFlag(MapMetadata(MF, VMap));
}
void CloneSubModule(llvm::Module &Dst, const Module &Src,
                    HandleGlobalVariableFtor HandleGlobalVariable,
                    HandleFunctionFtor HandleFunction, bool CloneInlineAsm) {

  ValueToValueMapTy VMap;

  if (CloneInlineAsm)
    Dst.appendModuleInlineAsm(Src.getModuleInlineAsm());

  // Copy global variables (but not initializers, yet).
  for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end();
       I != E; ++I) {
    GlobalVariable *GV = new GlobalVariable(
        Dst, I->getType()->getElementType(), I->isConstant(), I->getLinkage(),
        (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr,
        I->getThreadLocalMode(), I->getType()->getAddressSpace());
    GV->copyAttributesFrom(I);
    VMap[I] = GV;
  }

  // Loop over the functions in the module, making external functions as before
  for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) {
    Function *NF =
        Function::Create(cast<FunctionType>(I->getType()->getElementType()),
                         I->getLinkage(), I->getName(), &Dst);
    NF->copyAttributesFrom(I);
    VMap[I] = NF;
  }

  // Loop over the aliases in the module
  for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end();
       I != E; ++I) {
    auto *PTy = cast<PointerType>(I->getType());
    auto *GA =
        GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
                            I->getLinkage(), I->getName(), &Dst);
    GA->copyAttributesFrom(I);
    VMap[I] = GA;
  }

  // Now that all of the things that global variable initializer can refer to
  // have been created, loop through and copy the global variable referrers
  // over...  We also set the attributes on the global now.
  for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end();
       I != E; ++I) {
    GlobalVariable &GV = *cast<GlobalVariable>(VMap[I]);
    HandleGlobalVariable(GV, *I, VMap);
  }

  // Similarly, copy over function bodies now...
  //
  for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) {
    Function &F = *cast<Function>(VMap[I]);
    HandleFunction(F, *I, VMap);
  }

  // And aliases
  for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end();
       I != E; ++I) {
    GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
    if (const Constant *C = I->getAliasee())
      GA->setAliasee(MapValue(C, VMap));
  }

  // And named metadata....
  for (Module::const_named_metadata_iterator I = Src.named_metadata_begin(),
                                             E = Src.named_metadata_end();
       I != E; ++I) {
    const NamedMDNode &NMD = *I;
    NamedMDNode *NewNMD = Dst.getOrInsertNamedMetadata(NMD.getName());
    for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
      NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap));
  }

}