KeksimvsMaximvs
KeksimvsMaximvs

Reputation: 43

LLVM clone function pass to different module

I'm creating LLVM pass, loaded in opt as library, which takes function from hardcoded module and clones its function to the input module.

bool MyPass::runOnModule(llvm::Module &M)
{
  SMDiagnostic error;
  LLVMContext context;
  StringRef ImplAssembly = R"(
    define void @foo() {
      ret void
    }
  )";
  auto InjectedModule = parseAssemblyString(ImplAssembly, error, context);

  auto* ImplFunction = InjectedModule->getFunction("foo");
  auto DeclFunction = Function::Create(ImplFunction->getFunctionType(), ImplFunction->getLinkage(), "foo", M);

  VMap[ImplFunction] = DeclFunction;

  SmallVector<ReturnInst*, 8> Returns;
  CloneFunctionInto(DeclFunction, ImplFunction, VMap, false, Returns);
  return true;
}

Even though the pass successfully clones the function, opt throws EXC_BAD_ACCESS at LookupBucketFor function.

if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst())))

I want to know, whether the way of cloning functions is correct. If it is, then find the reason behind the crashes.

Upvotes: 0

Views: 1106

Answers (1)

KeksimvsMaximvs
KeksimvsMaximvs

Reputation: 43

After some experiments, found, that after passing the existing context of M, instead of empty variable context, the pass finished its work successfully, i.e. I should have passed existing context instead of creating the new one.

bool MyPass::runOnModule(llvm::Module &M)
{
  SMDiagnostic error;
  StringRef ImplAssembly = R"(
    define void @foo() {
      ret void
    }
  )";
  auto InjectedModule = parseAssemblyString(ImplAssembly, error, M.getContext());

  auto* ImplFunction = InjectedModule->getFunction("foo");
  auto DeclFunction = Function::Create(ImplFunction->getFunctionType(), ImplFunction->getLinkage(), "foo", M);

  VMap[ImplFunction] = DeclFunction;

  SmallVector<ReturnInst*, 8> Returns;
  CloneFunctionInto(DeclFunction, ImplFunction, VMap, false, Returns);
  return true;
}

Upvotes: 1

Related Questions