首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LLVM API优化运行

LLVM API优化运行
EN

Stack Overflow用户
提问于 2018-01-17 19:52:07
回答 1查看 387关注 0票数 0

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

代码语言:javascript
复制
int mult_add(int x, int y){
    if(x > 2){
        return y + 1 + 2;
    } else {
        return y - 1 + 2;
    }
}

通过这些调用:

代码语言:javascript
复制
clang -S -emit-llvm main.cpp
opt main.ll -o opt.ll -S -O2

我得到了正确的结果:

代码语言:javascript
复制
 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和legacy::FunctionPassManager进行优化时,优化根本不起作用,并且得到了又长又难看的代码:

代码语言:javascript
复制
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上运行passes效果很好。

顺便说一句,调用PMBuilder.populateModulePassManager的代码如下:

代码语言:javascript
复制
legacy::PassManager Passes;
legacy::FunctionPassManager FPasses(M2.get());
AddOptimizationPasses(Passes, FPasses, &(TheJIT->getTargetMachine()), 2, 0);
Passes.add(createPrintModulePass(outs()));
Passes.run(*M2);

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

代码语言:javascript
复制
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();

不幸的是,它不起作用。

EN

回答 1

Stack Overflow用户

发布于 2018-01-17 21:14:57

您是否忘记填充pass管理器?

代码语言:javascript
复制
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“可能无法满足您的需要。您可能正在寻找遗留的::PassManager(它可以包含任何类型的pass)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48300510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档