如何直接从LLVM源代码树中使用新编译的LLVM工具? [英] How do I use a freshly compiled LLVM tool directly from LLVM source tree?

查看:190
本文介绍了如何直接从LLVM源代码树中使用新编译的LLVM工具?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个针对X86体系结构的MachineFunctionPass,它导致了修改后的llc二进制文件.

I am writing a MachineFunctionPass targeting the X86 architecture which results in a modified llc binary.

为了测试修改后的llc版本,我创建了一堆.c程序,其MIR将由我的通行证处理.

In order to test my modified version of llc I have created a bunch of .c programs whose MIR will be handled by my pass.

为了简洁起见,我将包含源的目录直接添加到LLVM的源树中,特别是在$llvm_src_dir/lib/Target/X86/$examples_dir中:然后,通过将add_subdirectory()指令附加到$llvm_src_dir/lib/Target/X86/CMakeLists.txt,将其插入LLVM构建系统.

For the sake of cleanliness, I have added the directory including the sources directly into LLVM's source tree, specifically in $llvm_src_dir/lib/Target/X86/$examples_dir: I have then plugged it into LLVM build system by appending the add_subdirectory() directive to $llvm_src_dir/lib/Target/X86/CMakeLists.txt.

这样,我将能够直接从LLVM的构建目录构建所有内容.

In this way, I will be able to build everything directly from LLVM's build directory.

现在:如何在我的$examples_dir/CMakeLists.txt中指定使用LLVM的树内llc?

Now: how do I specify in my $examples_dir/CMakeLists.txt to use LLVM's in-tree llc?

这是来源的目录结构.由于只包含了有趣的目录",因此我省略了所有根目录的子目录.

This is the sources' directory structure. I have omitted all the root's children directories since I've only included the "interesting ones".

LLVM在tools/llc中定义了llc目标,而我的源代码在目录中的位置更深,如以下树所示:

LLVM's defines the llc target in tools/llc while my sources live quite deeper in the directory as shown in the following tree:

llvm_src_dir
├── bindings
├── cmake
├── docs
├── examples
├── include
├── lib
    └── Target
        └── X86
            /* 
             * My git repo is here. LLVM's and
             * my MachineFunctionPass' files
             * live here 
            */
            ├── .git
            ├── CMakeLists.txt // This is LLVM's X86 CMakeLists.txt
            └── examples
                └── CMakeLists.txt // My CMakeLists.txt
├── projects
├── resources
├── runtimes
├── test
├── tools
    └── llc
        └── CMakeLists.txt // this is where LLVM's llc target is defined
├── unittests
└── utils

lib/Target/X86/CMakeLists.txt

这是我编辑目标架构的CMakeLists.txt的方式:

lib/Target/X86/CMakeLists.txt

This is how I edited the CMakeLists.txt of the architecture I'm targeting:

set (CMAKE_CXX_STANDARD 14)
set(LLVM_TARGET_DEFINITIONS X86.td)

tablegen(LLVM X86GenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM X86GenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM X86GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
tablegen(LLVM X86GenCallingConv.inc -gen-callingconv)
tablegen(LLVM X86GenDAGISel.inc -gen-dag-isel)
tablegen(LLVM X86GenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM X86GenEVEX2VEXTables.inc -gen-x86-EVEX2VEX-tables)
tablegen(LLVM X86GenFastISel.inc -gen-fast-isel)
tablegen(LLVM X86GenGlobalISel.inc -gen-global-isel)
tablegen(LLVM X86GenInstrInfo.inc -gen-instr-info)
tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank)
tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info)
tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)

if (X86_GEN_FOLD_TABLES)
    tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables)
endif ()

add_public_tablegen_target(X86CommonTableGen)

set(MY_SOURCES
        a.cpp
        b.cpp
        c.cpp
        )

set(sources
        ShadowCallStack.cpp
        X86AsmPrinter.cpp
        X86CallFrameOptimization.cpp
        X86CallingConv.cpp
        X86CallLowering.cpp
        X86CmovConversion.cpp
        X86DomainReassignment.cpp
        X86ExpandPseudo.cpp
        X86FastISel.cpp
        X86FixupBWInsts.cpp
        X86FixupLEAs.cpp
        X86AvoidStoreForwardingBlocks.cpp
        X86FixupSetCC.cpp
        X86FlagsCopyLowering.cpp
        X86FloatingPoint.cpp
        X86FrameLowering.cpp
        X86InstructionSelector.cpp
        X86ISelDAGToDAG.cpp
        X86ISelLowering.cpp
        X86IndirectBranchTracking.cpp
        X86InterleavedAccess.cpp
        X86InstrFMA3Info.cpp
        X86InstrFoldTables.cpp
        X86InstrInfo.cpp
        X86EvexToVex.cpp
        X86LegalizerInfo.cpp
        X86MCInstLower.cpp
        X86MachineFunctionInfo.cpp
        X86MacroFusion.cpp
        X86OptimizeLEAs.cpp
        X86PadShortFunction.cpp
        X86RegisterBankInfo.cpp
        X86RegisterInfo.cpp
        X86RetpolineThunks.cpp
        X86SelectionDAGInfo.cpp
        X86ShuffleDecodeConstantPool.cpp
        X86SpeculativeLoadHardening.cpp
        X86Subtarget.cpp
        X86TargetMachine.cpp
        X86TargetObjectFile.cpp
        X86TargetTransformInfo.cpp
        X86VZeroUpper.cpp
        X86WinAllocaExpander.cpp
        X86WinEHState.cpp
        ${MY_SOURCES}
        )

add_llvm_target(X86CodeGen ${sources})

add_subdirectory(AsmParser)
add_subdirectory(Disassembler)
add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)
add_subdirectory(Utils)
add_subdirectory(examples) // my examples directory

我已经尝试过的东西

我当前正在使用find_path()查找llc,但这要求llc已被 编译,因此如果我不编译,我的示例CMakeLists.txt将无法通过验证llc提前.

What I have already tried

I am currently using find_path() to find llc but this requires llc to be already compiled and therefore my examples CMakeLists.txt will fail the validation if I don't compile llc beforehand.

假定路径存在,我最终在CMakeLists.txt中使用add_custom_command()指令在CMakeLists.txt中使用llc,但是我认为这太过分了.

Assuming the path exists, I finally use an add_custom_command() directive to use llc in my CMakeLists.txt but this is way too hacky in my opinion.

基本上,我需要添加llc目标作为目标的依赖项,然后使用llc的路径将示例的.bc文件编译为.s.

Basically, I need to add the llc target as a dependency for my targets and then use llc's path to compile my examples' .bc files into .s.

有什么想法吗?

非常感谢您!

推荐答案

我看到了两种可能的解决方案,现在让我介绍一个简单的解决方案.

I see two possible solutions and for now let me present simpler one.

project(nested-toolchain C CXX)

# Assume that `llc` target is created somewhere within project
# Even if it is created in later `add_subdirectory` calls,
# We can defer evaluation to its path using generator expression $<TARGET_FILE:llc>

# This is the magic.
# It tells cmake how to produce test1.s from test1.bc using llc binary
# Also will track test1.bc changes and set test1.s as dirty when needed
add_custom_command(OUTPUT test1.s COMMAND $<TARGET_FILE:llc> test1.bc DEPENDS test1.bc)
add_custom_command(OUTPUT test2.s COMMAND $<TARGET_FILE:llc> test2.bc DEPENDS test2.bc)

# Now merge custom commands into single target which can be called by make/ninja/...
# simply call `make tests` to run two commands listed above (and compile llc before that)
add_custom_target(tests SOURCES test1.s test2.s)

总结:首先,我们知道我们的CMake项目可以从llvm-sources的某个地方生成llc二进制文件.此二进制文件可用于在指定了magic命令的情况下生成test.s文件. 它们取决于相应的.bc文件.这些.bc文件通过add_custom_target连接到单个目标tests中.

To sum up: first we know that our CMake project can produce llc binary somewhere from llvm-sources. This binary can be used to produce test.s files with magic command specified. They depend on corresponding .bc files. These .bc files are joined into single target tests via add_custom_target.

我使用add_custom_target来使示例保持最小,它有一个缺陷:调用make tests总是将调用所有llc命令,因为自定义目标始终被认为是过时的".

I've used add_custom_target to keep example minimal and it has one flaw: calling make tests will always call all llc commands, as custom targets are always considered "out of date".

如果要在.s文件上使用其他工具,我建议类似地链接另一个add_custom_command,并使用add_custom_target完成链接.

If you want to use another tool over .s files, I recommend to chain yet another add_custom_command analogically and use add_custom_target to finish the chain.

只要您正在测试单个二进制文件(llc),此方法就应该起作用.如果您想测试整个工具链,我会选择try_compile.

This approach should work as long as you are testing single binary (llc). If you wanted to test whole toolchain, I'd go for try_compile.

为完整起见,对于给定的llc.cpp文件:

For completeness, for llc.cpp file as given:

// Just print args
#include <iostream>
int main(int argc, char **argv) {
  for (int i = 0; i < argc; i++) {
    std::cout << argv[i] << ' ';
  }
  std::cout << "\n";
  return 0;
}

ninja tests导致:

$ ninja tests
[1/2] Generating test2.s
/home/stackoverflow/nested-toolchain/build/llc test2.bc 
[2/2] Generating test1.s
/home/stackoverflow/nested-toolchain/build/llc test1.bc 

这篇关于如何直接从LLVM源代码树中使用新编译的LLVM工具?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆