Exemplo n.º 1
0
Generator::~Generator() {
  std::map<std::string, llvm::IRBuilder<> *> tors = {
    { "llvm.global_ctors", ctor }, { "llvm.global_dtors", dtor }
  };
  auto base_str =
      llvm::PointerType::get(llvm::Type::getInt8Ty(mod->getContext()), 0);
  auto int32_ty = llvm::Type::getInt32Ty(mod->getContext());
  llvm::Type *struct_elements[] = {
    int32_ty,
    llvm::PointerType::get(llvm::FunctionType::get(
                               llvm::Type::getVoidTy(mod->getContext()), false),
                           0),
    base_str
  };
  auto struct_ty = llvm::StructType::create(struct_elements);
  auto array_ty = llvm::ArrayType::get(struct_ty, 1);
  for (auto &tor : tors) {
    tor.second->CreateRetVoid();
    auto link = new llvm::GlobalVariable(*mod, array_ty, false,
                                         llvm::GlobalVariable::AppendingLinkage,
                                         0, tor.first);
    llvm::Constant *constants[] = { llvm::ConstantStruct::get(
        struct_ty, llvm::ConstantInt::get(int32_ty, 65535),
        tor.second->GetInsertBlock()->getParent(),
        llvm::ConstantPointerNull::get(base_str)) };
    link->setInitializer(llvm::ConstantArray::get(array_ty, constants));
    delete tor.second;
  }
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
llvm::Constant *Generator::createString(const std::string &str) {
  auto iterator = constant_pool.find(str);
  if (iterator != constant_pool.end()) {
    return iterator->second;
  }

  auto array = llvm::ConstantDataArray::getString(mod->getContext(), str);
  auto global_variable = new llvm::GlobalVariable(
      *mod, llvm::ArrayType::get(llvm::Type::getInt8Ty(mod->getContext()),
                                 str.length() + 1),
      true, llvm::GlobalValue::PrivateLinkage, 0, ".str");
  global_variable->setAlignment(1);
  global_variable->setInitializer(array);
  auto zero =
      llvm::ConstantInt::get(llvm::Type::getInt8Ty(mod->getContext()), 0);
  std::vector<llvm::Value *> indicies;
  indicies.push_back(zero);
  indicies.push_back(zero);
  auto result = llvm::ConstantExpr::getGetElementPtr(
      global_variable->getValueType(), global_variable, indicies);
  constant_pool[str] = result;
  return result;
}