Kaleidoscope 语言: Compiling to Object Code

在本章中,我们学习如何跨平台编译

但是本章节的代码,和之前几章节是脱节的,尤其是如果在原来的代码基础上增加 Export to Object,是无法成功导出的 这里和 JIT 那部分内容冲突,代码上增加了宏来跳过

支持的平台 #

通过

llvm-as < /dev/null | llc -march=x86 -mattr=help

我们得知 LLVM 支持的平台

修改支持平台 #

我们之前的代码中都是

llvm::InitializeNativeTarget (); // 支持当前平台 nativeTarget

我们修改为

-   llvm::InitializeNativeTarget ();
-   llvm::InitializeNativeTargetAsmPrinter ();
-   llvm::InitializeNativeTargetAsmParser ();
+
+
+

增加生成逻辑 #


// 获得当前目标的
auto TargetTriple = llvm::sys::getDefaultTargetTriple();
TheModule->setTargetTriple(TargetTriple);

std::string Error;
auto Target = llvm::TargetRegistry::lookupTarget(TargetTriple, Error);

// 如果找不到目标就直接报错退出
if (!Target) {
    llvm::errs() << Error;
    return 1;
}

auto CPU = "generic";
auto Features = "";

llvm::TargetOptions opt;
auto RM = llvm::Optional<llvm::Reloc::Model>();
auto TheTargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);

TheModule->setDataLayout(TheTargetMachine->createDataLayout());

auto Filename = "output.o";
std::error_code EC;
llvm::raw_fd_ostream dest(Filename, EC, llvm::sys::fs::OF_None);

if (EC) {
    llvm::errs() << "Could not open file: " << EC.message();
    return 1;
}

llvm::legacy::PassManager pass;
auto FileType = llvm::CGFT_ObjectFile;

if (TheTargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) {
    llvm::errs() << "TheTargetMachine can't emit a file of this type";
    return 1;
}

pass.run(*TheModule);
dest.flush();

llvm::outs() << "Wrote " << Filename << "\n";

Try it #

ready> def average(x y) (x + y) * 0.5;
^D
Wrote output.o

$ llvm-objdump -d cmake-build-debug/output.o                 

cmake-build-debug/output.o:     file format mach-o 64-bit x86-64

Disassembly of section __TEXT,__text:

0000000000000000 <_average>:
       0: f2 0f 11 44 24 f0             movsd   %xmm0, -16(%rsp)
       6: f2 0f 11 4c 24 f8             movsd   %xmm1, -8(%rsp)
       c: f2 0f 58 c1                   addsd   %xmm1, %xmm0
      10: f2 0f 59 05 08 00 00 00       mulsd   8(%rip), %xmm0          ## 0x20 <_average+0x20>
      18: c3                            retq


$ ./main              
average of 3.0 and 4.0: 3.5

参考 #

comments powered by Disqus