LLVM API优化运行

时间:2018-01-17 11:52:07

标签: c++ optimization clang llvm

我正在尝试使用通过调用CLANG API获得的LLVM IR执行-O2优化。遗憾的是,优化仅适用于使用手动调用创建的IR。我有以下功能:

int mult_add(int x, int y){
    if(x > 2){
        return y + 1 + 2;
    } else {
        return y - 1 + 2;
    }
}

通过这些电话:

clang -S -emit-llvm main.cpp
opt main.ll -o opt.ll -S -O2

我得到了正确的结果:

 define i32 @_Z8mult_addii(i32, i32) local_unnamed_addr #0 {
  %3 = icmp sgt i32 %0, 2
  %.sink = select i1 %3, i32 3, i32 1
  %4 = add nsw i32 %.sink, %1
  ret i32 %4
}

不幸的是,当我通过LLVM API使用legacy :: PassManager和遗留:: FunctionPassManager优化时,它根本不起作用并且得到了很长的丑陋代码:

define i32 @_Z8mult_addii(i32, i32) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  %5 = alloca i32, align 4
  store i32 %0, i32* %4, align 4
  store i32 %1, i32* %5, align 4
  %6 = load i32, i32* %4, align 4
  %7 = icmp sgt i32 %6, 2
  br i1 %7, label %8, label %12

; <label>:8:                                      ; preds = %2
  %9 = load i32, i32* %5, align 4
  %10 = add nsw i32 %9, 1
  %11 = add nsw i32 %10, 2
  store i32 %11, i32* %3, align 4
  br label %16

; <label>:12:                                     ; preds = %2
  %13 = load i32, i32* %5, align 4
  %14 = sub nsw i32 %13, 1
  %15 = add nsw i32 %14, 2
  store i32 %15, i32* %3, align 4
  br label %16

; <label>:16:                                     ; preds = %12, %8
  %17 = load i32, i32* %3, align 4
  ret i32 %17
}

似乎CLANG在一些不可挽回的状态下创建了IR?因为在手动创建的IR上运行传递可以正常工作。

顺便说一下,调用PMBuilder.populateModulePassManager,这里是代码:

legacy::PassManager Passes;
legacy::FunctionPassManager FPasses(M2.get());
AddOptimizationPasses(Passes, FPasses, &(TheJIT->getTargetMachine()), 2, 0);
Passes.add(createPrintModulePass(outs()));
Passes.run(*M2);

AddOptimizationPasses被从opt实用程序中窃取并简化:

static void AddOptimizationPasses(legacy::PassManagerBase &MPM,
                                  legacy::FunctionPassManager &FPM,
                                  TargetMachine *TM, unsigned OptLevel,
                                  unsigned SizeLevel) {
    FPM.add(createVerifierPass());

  PassManagerBuilder Builder;
  Builder.OptLevel = OptLevel;
  Builder.SizeLevel = SizeLevel;

  Builder.Inliner = createFunctionInliningPass(50);
  Builder.DisableUnitAtATime = true;//!UnitAtATime;
  Builder.DisableUnrollLoops = false;

  if (TM)
    TM->adjustPassManager(Builder);

  //Builder.populateFunctionPassManager(FPM);
  Builder.populateModulePassManager(MPM);
}
By the way, initialisation is following:

InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();

不幸的是,它不起作用。

1 个答案:

答案 0 :(得分:0)

您是否忘记填充通行证经理?

PassManagerBase& PM = ...; // create the pass manager.
PassManagerBuilder PMBuilder;
PMBuilder.OptLevel = 2;
PMBuilder.DisableUnrollLoops = false;
PMBuilder.Inliner = createFunctionInliningPass(50);
PMBuilder.populateModulePassManager(PM);
Module& = ...; // your IR module here
PM.run(M);

请注意,“FunctionPassManager”可能无法满足您的需求。您可能正在寻找legacy :: PassManager(可以保存任何类型的传递)。