Skip to content

llvm sroa #17

@lfeng14

Description

@lfeng14

疑问:

  • sroa pass是在mem2reg之前执行,为什么不首先执行mem2reg?
    SROA 必须在 mem2reg 之前执行,因为 mem2reg 只能处理“标量 alloca”,而 SROA 的任务就是把复杂的 alloca 拆成标量。
  • 整体流程:
    • 见评论
  • 什么是sroa的slice ?
    • slice = alloca 的一个“可独立处理的内存片段”
    • slice 由访问偏移决定
    • slice 决定 alloca 如何被拆分
    • 每个 slice 最终变成一个标量 alloca → 再被 mem2reg 提升为 SSA

实操

  • 17版本构建时打开assert;19版本貌似不识别选项后面证实是正常的;
    ./install/bin/opt -S --passes=sroa demo.ll -debug 
    opt: Unknown command line argument '-debug'.  Try: './install/bin/opt --help'
    opt: Did you mean '--debugify'?
    
    $cat > demo.ll
    define i32 @foo(i32 %0, i32 %1) {
    entry:
      %2 = alloca i32, align 4
      %3 = alloca i32, align 4
      store i32 %0, ptr %2, align 4
      store i32 %1, ptr %3, align 4
      %4 = load i32, ptr %2, align 4
      %5 = load i32, ptr %3, align 4
      %6 = mul i32 %4, %4
      %7 = mul i32 %5, %5
      %8 = add i32 %6, %7
      ret i32 %8
    }
    ^C
    $ opt -S --passes=sroa demo.ll -debug 
    Args: opt -S --passes=sroa demo.ll -debug 
    SROA function: foo
    SROA alloca:   %3 = alloca i32, align 4
    define i32 @foo(i32 %0, i32 %1) {
    entry:
      %2 = alloca i32, align 4
      %3 = alloca i32, align 4
      store i32 %0, ptr %2, align 4   # dele 先存后取,中间没有别名
      store i32 %1, ptr %3, align 4   # 同理
      %4 = load i32, ptr %2, align 4  # dele 先存后取,中间没有别名
      %5 = load i32, ptr %3, align 4  # 同理
      %6 = mul i32 %4, %4
      %7 = mul i32 %5, %5
      %8 = add i32 %6, %7
      ret i32 %8
    }
    
      Rewriting FCA loads and stores...
    Slices of alloca:   %3 = alloca i32, align 4
      [0,4) slice #0 (splittable)
        used by:   store i32 %1, ptr %3, align 4
      [0,4) slice #1 (splittable)
        used by:   %5 = load i32, ptr %3, align 4
    Pre-splitting loads and stores
      Searching for candidate loads and stores
    Rewriting alloca partition [0,4) to:   %3 = alloca i32, align 4
      rewriting [0,4) slice #0 (splittable)
       Begin:(0, 4) NewBegin:(0, 4) NewAllocaBegin:(0, 4)
        original:   store i32 %1, ptr %3, align 4
              to:   store i32 %1, ptr %3, align 4
      rewriting [0,4) slice #1 (splittable)
       Begin:(0, 4) NewBegin:(0, 4) NewAllocaBegin:(0, 4)
        original:   %5 = load i32, ptr %3, align 4
              to:   %.0.load = load i32, ptr %3, align 4
      Speculating PHIs
      Rewriting Selects
    Deleting dead instruction:   %5 = load i32, ptr %3, align 4
    Deleting dead instruction:   store i32 %1, ptr %3, align 4
    SROA alloca:   %2 = alloca i32, align 4
    define i32 @foo(i32 %0, i32 %1) {
    entry:
      %2 = alloca i32, align 4
      %3 = alloca i32, align 4
      store i32 %0, ptr %2, align 4
      store i32 %1, ptr %3, align 4
      %4 = load i32, ptr %2, align 4
      %.0.load = load i32, ptr %3, align 4
      %5 = mul i32 %4, %4
      %6 = mul i32 %.0.load, %.0.load
      %7 = add i32 %5, %6
      ret i32 %7
    }
    
      Rewriting FCA loads and stores...
    Slices of alloca:   %2 = alloca i32, align 4
      [0,4) slice #0 (splittable)
        used by:   store i32 %0, ptr %2, align 4
      [0,4) slice #1 (splittable)
        used by:   %4 = load i32, ptr %2, align 4
    Pre-splitting loads and stores
      Searching for candidate loads and stores
    Rewriting alloca partition [0,4) to:   %2 = alloca i32, align 4
      rewriting [0,4) slice #0 (splittable)
       Begin:(0, 4) NewBegin:(0, 4) NewAllocaBegin:(0, 4)
        original:   store i32 %0, ptr %2, align 4
              to:   store i32 %0, ptr %2, align 4
      rewriting [0,4) slice #1 (splittable)
       Begin:(0, 4) NewBegin:(0, 4) NewAllocaBegin:(0, 4)
        original:   %4 = load i32, ptr %2, align 4
              to:   %.0.load1 = load i32, ptr %2, align 4
      Speculating PHIs
      Rewriting Selects
    Deleting dead instruction:   %4 = load i32, ptr %2, align 4
    Deleting dead instruction:   store i32 %0, ptr %2, align 4
    Promoting allocas with mem2reg...
    ; ModuleID = 'demo.ll'
    source_filename = "demo.ll"
    
    define i32 @foo(i32 %0, i32 %1) {
    entry:
      %2 = mul i32 %0, %0
      %3 = mul i32 %1, %1
      %4 = add i32 %2, %3
      ret i32 %4
    }
    
    

参考

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions