How to set Target/Triple of ExecutionEngine

I don't know if I'm setting the triple of my execution engine
correctly. This is leading to an issue where a struct `{i8,i64}` is not
getting the same layout as the ABI expects.

I setup my engine/module like this:

 llvm::SmallVector<std::string,2> mattrs;
 llvm::EngineBuilder builder\{ unique\_ptr<llvm::Module>\(module\) \};
 llvm::ExecutionEngine \* ee = builder\.
    setErrorStr\( &errStr \)\.
    setEngineKind\( llvm::EngineKind::JIT \)\.
    setTargetOptions\( topts \)\.
    create\(builder\.selectTarget\(

llvm::Triple(llvm::Triple::normalize(platform::target->triple)), "", "",
mattrs ));

module\->setDataLayout\( ee\->getDataLayout\(\) \);

Where `module` is my `llvm::Module` with the generated IR code.

I'm using the triple `x86_64-pc-linux-gnu`, the same as clang on the
machine, but getting different alignments. I'm assuming the above is
somehow not creating the correct layout. Perhaps there's an ordering issue?

Taking one step back, I'm not clear I'm even setting the
triple/DataLayout on the module correctly:

module = new llvm::Module\( "test", \*llvm\_context \);
module\->setTargetTriple\( platform::target\->triple \);

Is that enough to create an appropriate DataLayout for the module? I
don't see anyway to convert a triple to a DataLayout, so I can't call
`setDataLayout`.

Hi edaqa,

You might need to set your TargetOptions before calling selectTarget. E.g.

builder.setTargetOptions(Opts).selectTarget(…);

Or you could just let EngineBuilder call selectTarget for you (which is what the no-argument version of EngineBuilder::create does):

llvm::ExecutionEngine * ee = builder.

setErrorStr( &errStr ).
setEngineKind( llvm::EngineKind::JIT ).
setTargetOptions( topts ).
setMArch(arch).
setMAttrs(mattrs).
create();

If those are still failing, it would be interesting to get the data layout string that you are getting from the ExecutionEngine instance and compare it to what you are expecting.

Cheers,
Lang.

Yes, I think ordering was a problem. I've moved my target machine setup
to immediately after creating the `Module` now, before adding any IR,
and it seems to work.

module = new llvm::Module\( "test", \*llvm\_context \);
module\->setTargetTriple\( platform::target\->triple \);

std::string err\_str;
auto triple\_str = llvm::Triple::normalize\(platform::target\->triple\);
llvm::Target const \*  target = llvm::TargetRegistry::lookupTarget\(

triple_str, err_str );
STATE_CHECK( target, err_str );
auto targetMachine = target->createTargetMachine(triple_str,
"generic", "", llvm::TargetOptions{},
llvm::Optional<llvm::Reloc::Model>());

module\-&gt;setDataLayout\( targetMachine\-&gt;createDataLayout\(\) \);