Initializations at the beginning of LLVM application

143 阅读1分钟

There are six initialization steps to go, mostly registers needed constructors.

  1. the target. (represent a specific ISA)
  2. the target machine. ( represent a concrete machine for a target, with subtargets for specific CPUs with different features and attributes.)
  3. MC layer. (Machine Code layer, convert Machine IR to asm file or object file)
  4. AsmPrinter (For output asm file or object file)
  5. AsmParser (Optional)
  6. Disassembler (Optional)

By the way,there are three layers started from LLVM IR Layer, the Machine IR Layer and the Machine Code Layer.

// do some initialization for llvm application
// and clean up managed static variable in destructor.
InitLLVM X(argc, argv);

LLVMContext Context;

// setup target.
InitializeAllTargets();
LLVMInitializeXXXTargetInfo();
extern "C" void LLVMInitializeCpu0TargetInfo() {
  RegisterTarget<Triple::cpu0,
                 /*HasJIT=*/true>
      X(TheCpu0Target, "cpu0", "CPU0 (32-bit big endian)", "Cpu0");
  RegisterTarget<Triple::cpu0el,
                 /*HasJIT=*/true>
      Y(TheCpu0elTarget, "cpu0el", "CPU0 (32-bit little endian)", "Cpu0");
}

// then register all needed class constructor into target.

// register target machine in target.
LLVMInitializeXXXTarget();
extern "C" void LLVMInitializeCpu0Target() {
  // Register the target.
  //- Big endian Target Machine
  RegisterTargetMachine<Cpu0ebTargetMachine> X(TheCpu0Target);
  //- Little endian Target Machine
  RegisterTargetMachine<Cpu0elTargetMachine> Y(TheCpu0elTarget);
}

// MC layer initialization.
InitializeAllTargetMCs();
LLVMInitializeXXXTargetMC();
extern "C" void LLVMInitializeCpu0TargetMC() {
  for (Target *T : {&TheCpu0Target, &TheCpu0elTarget}) {
  
    // Register the MC asm info.
    RegisterMCAsmInfoFn X(*T, createCpu0MCAsmInfo);

    // Register the MC instruction info.
    TargetRegistry::RegisterMCInstrInfo(*T, createCpu0MCInstrInfo);

    // Register the MC register info.
    TargetRegistry::RegisterMCRegInfo(*T, createCpu0MCRegisterInfo);

    // Register the elf streamer.
    TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);

    // Register the asm target streamer.
    TargetRegistry::RegisterAsmTargetStreamer(*T, createCpu0AsmTargetStreamer);

    // Register the asm backend.
    TargetRegistry::RegisterMCAsmBackend(*T, createCpu0AsmBackend);
    
    // Register the MC subtarget info.
    TargetRegistry::RegisterMCSubtargetInfo(*T, createCpu0MCSubtargetInfo);
    
    // Register the MC instruction analyzer.
    TargetRegistry::RegisterMCInstrAnalysis(*T, createCpu0MCInstrAnalysis);
    
    // Register the MCInstPrinter.
    TargetRegistry::RegisterMCInstPrinter(*T, createCpu0MCInstPrinter);
  }
  
  // Register the MC Code Emitter
  TargetRegistry::RegisterMCCodeEmitter(TheCpu0Target,
                                        createCpu0MCCodeEmitterEB);
  TargetRegistry::RegisterMCCodeEmitter(TheCpu0elTarget,
                                        createCpu0MCCodeEmitterEL);
}

// if you want to output asm file or object file.
InitializeAllAsmPrinters();
LLVMInitializeXXXAsmPrinter();
extern "C" void LLVMInitializeCpu0AsmPrinter() {
  RegisterAsmPrinter<Cpu0AsmPrinter> X(TheCpu0Target);
  RegisterAsmPrinter<Cpu0AsmPrinter> Y(TheCpu0elTarget);
}

// if you want to support inline asm.
InitializeAllAsmParsers();
LLVMInitializeXXXAsmParser();
extern "C" void LLVMInitializeCpu0AsmParser() {
  RegisterMCAsmParser<Cpu0AsmParser> X(TheCpu0Target);
  RegisterMCAsmParser<Cpu0AsmParser> Y(TheCpu0elTarget);
}

// if you want to disassemble binary code.
InitializeAllDisassemblers();
LLVMInitializeXXXDisassembler();
extern "C" void LLVMInitializeCpu0Disassembler() {
  // Register the disassembler.
  TargetRegistry::RegisterMCDisassembler(TheCpu0Target, createCpu0Disassembler);
  TargetRegistry::RegisterMCDisassembler(TheCpu0elTarget,
                                         createCpu0elDisassembler);
}