Ejemplo n.º 1
0
llvm::Value* CreateExpr::build(FuncBuilder& builder)
{
	auto llvmTypePtr = ctor->getLlvmType(builder.modBuilder);
	auto llvmType = llvmTypePtr->getTypeAtIndex(0u);
	auto BB = builder.ir.GetInsertBlock();
	auto sizeOf = llvm::ConstantExpr::getSizeOf(llvmType);
	auto alloc = llvm::CallInst::CreateMalloc(
		BB,
		sizeOf->getType(),
		llvmType,
		sizeOf);

	BB->getInstList().push_back(alloc);

	for(auto i = 0u; i < parameters.size(); ++i)
	{
		auto slot = builder.ir.CreateStructGEP(alloc, i + 2);
		auto value = parameters[i]->build(builder);
		builder.ir.CreateStore(value, slot);
	}

	auto rcSlot = builder.ir.CreateStructGEP(alloc, 0);
	builder.ir.CreateStore(builder.ir.getInt32(1), rcSlot);

	auto tagSlot = builder.ir.CreateStructGEP(alloc, 1);
	builder.ir.CreateStore(builder.ir.getInt32(ctor->tag), tagSlot);

	return builder.ir.CreateBitCast(alloc, type->llvmType(builder.modBuilder));
}
Ejemplo n.º 2
0
// make a copy of all blocks and instructions in srcblocks
// - map values to clones
// - redirect srcTarget to continueWith
// - set "funclet" attribute inside catch/cleanup pads
// - inside funclets, replace "unreachable" with "branch cleanupret"
void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
                 std::vector<llvm::BasicBlock *> &blocks,
                 llvm::BasicBlock *continueWith, llvm::BasicBlock *unwindTo,
                 llvm::Value *funclet) {
  llvm::ValueToValueMapTy VMap;
  // map the terminal branch to the new target
  if (continueWith)
    if (auto term = srcblocks.back()->getTerminator())
      if (auto succ = term->getSuccessor(0))
        VMap[succ] = continueWith;

  for (auto bb : srcblocks) {
    llvm::Function *F = bb->getParent();

    auto nbb = llvm::BasicBlock::Create(bb->getContext(), bb->getName());
    // Loop over all instructions, and copy them over.
    for (auto &II : *bb) {
      llvm::Instruction *Inst = &II;
      llvm::Instruction *newInst = nullptr;
      if (funclet &&
          !llvm::isa<llvm::DbgInfoIntrinsic>(Inst)) { // IntrinsicInst?
        if (auto IInst = llvm::dyn_cast<llvm::InvokeInst>(Inst)) {
          auto invoke = llvm::InvokeInst::Create(
              IInst, llvm::OperandBundleDef("funclet", funclet));
          newInst = invoke;
        } else if (auto CInst = llvm::dyn_cast<llvm::CallInst>(Inst)) {
          auto call = llvm::CallInst::Create(
              CInst, llvm::OperandBundleDef("funclet", funclet));
          newInst = call;
        } else if (funclet && llvm::isa<llvm::UnreachableInst>(Inst)) {
          newInst = llvm::BranchInst::Create(continueWith); // to cleanupret
        }
      }
      if (!newInst)
        newInst = Inst->clone();

      nbb->getInstList().push_back(newInst);
      VMap[Inst] = newInst; // Add instruction map to value.
      if (unwindTo)
        if (auto dest = getUnwindDest(Inst))
          VMap[dest] = unwindTo;
    }
    nbb->insertInto(F, continueWith);
    VMap[bb] = nbb;
    blocks.push_back(nbb);
  }

  remapBlocks(blocks, VMap);
}
Ejemplo n.º 3
0
std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id)
{
	Guard g{x_cacheMutex};

	if (g_mode != CacheMode::on && g_mode != CacheMode::read)
		return nullptr;

	// TODO: Disabled because is not thread-safe.
	//if (g_listener)
	//	g_listener->stateChanged(ExecState::CacheLoad);

	DLOG(cache) << id << ": search\n";
	if (!CHECK(!g_lastObject))
		g_lastObject = nullptr;

	llvm::SmallString<256> cachePath{getVersionedCacheDir()};
	llvm::sys::path::append(cachePath, id);

	if (auto r = llvm::MemoryBuffer::getFile(cachePath, -1, false))
		g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer());
	else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory))
		DLOG(cache) << r.getError().message(); // TODO: Add warning log

	if (g_lastObject)  // if object found create fake module
	{
		DLOG(cache) << id << ": found\n";
		auto&& context = llvm::getGlobalContext();
		auto module = llvm::make_unique<llvm::Module>(id, context);
		auto mainFuncType = llvm::FunctionType::get(llvm::Type::getVoidTy(context), {}, false);
		auto mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, id, module.get());
		auto bb = llvm::BasicBlock::Create(context, {}, mainFunc);
		bb->getInstList().push_back(new llvm::UnreachableInst{context});
		return module;
	}
	DLOG(cache) << id << ": not found\n";
	return nullptr;
}