Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorder stack spills so that constants come later. #130329

Merged
merged 1 commit into from
Sep 26, 2024

Commits on Sep 17, 2024

  1. Reorder stack spills so that constants come later.

    Currently constants are "pulled forward" and have their stack spills emitted
    first. This confuses LLVM as to where to place breakpoints at function
    entry, and results in argument values being wrong in the debugger. It's
    straightforward to avoid emitting the stack spills for constants until
    arguments/etc have been introduced in debug_introduce_locals, so do that.
    
    Example LLVM IR (irrelevant IR elided):
    Before:
    
    define internal void @_ZN11rust_1289457binding17h2c78f956ba4bd2c3E(i64 %a, i64 %b, double %c) unnamed_addr #0 !dbg !178 {
    start:
      %c.dbg.spill = alloca [8 x i8], align 8
      %b.dbg.spill = alloca [8 x i8], align 8
      %a.dbg.spill = alloca [8 x i8], align 8
      %x.dbg.spill = alloca [4 x i8], align 4
      store i32 0, ptr %x.dbg.spill, align 4, !dbg !192            ; LLVM places breakpoint here.
        #dbg_declare(ptr %x.dbg.spill, !190, !DIExpression(), !192)
      store i64 %a, ptr %a.dbg.spill, align 8
        #dbg_declare(ptr %a.dbg.spill, !187, !DIExpression(), !193)
      store i64 %b, ptr %b.dbg.spill, align 8
        #dbg_declare(ptr %b.dbg.spill, !188, !DIExpression(), !194)
      store double %c, ptr %c.dbg.spill, align 8
        #dbg_declare(ptr %c.dbg.spill, !189, !DIExpression(), !195)
      ret void, !dbg !196
    }
    
    After:
    define internal void @_ZN11rust_1289457binding17h2c78f956ba4bd2c3E(i64 %a, i64 %b, double %c) unnamed_addr #0 !dbg !178 {
    start:
      %x.dbg.spill = alloca [4 x i8], align 4
      %c.dbg.spill = alloca [8 x i8], align 8
      %b.dbg.spill = alloca [8 x i8], align 8
      %a.dbg.spill = alloca [8 x i8], align 8
      store i64 %a, ptr %a.dbg.spill, align 8
        #dbg_declare(ptr %a.dbg.spill, !187, !DIExpression(), !192)
      store i64 %b, ptr %b.dbg.spill, align 8
        #dbg_declare(ptr %b.dbg.spill, !188, !DIExpression(), !193)
      store double %c, ptr %c.dbg.spill, align 8
        #dbg_declare(ptr %c.dbg.spill, !189, !DIExpression(), !194)
      store i32 0, ptr %x.dbg.spill, align 4, !dbg !195            ; LLVM places breakpoint here.
        #dbg_declare(ptr %x.dbg.spill, !190, !DIExpression(), !195)
      ret void, !dbg !196
    }
    
    Note in particular the position of the "LLVM places breakpoint here" comment
    relative to the stack spills for the function arguments. LLVM assumes that
    the first instruction with with a debug location is the end of the prologue.
    As LLVM does not currently offer front ends any direct control over the
    placement of the prologue end reordering the IR is the only mechanism available
    to fix argument values at function entry in the presence of MIR optimizations
    like SingleUseConsts. Fixes rust-lang#128945
    khuey committed Sep 17, 2024
    Configuration menu
    Copy the full SHA
    652b502 View commit details
    Browse the repository at this point in the history