On 3/31/25 21:54, Jeff Law wrote:
> And if that's the case then you can't simply skip an abnormal edge.  You 
> have to do something sensible.
>
> That "something sensible" has traditionally been to ensure there is 
> never a need propagated to an edge since you can't insert on an abnormal 
> critical edge.
>
>> [ ... ]
> If there is a need in the block, then every path to the block must have 
> the right value.  That's precisely my point.  You can't simply skip an 
> edge in this case.
>
> What needs to happen is you need to find a way to ensure there is no 
> need at the start of the block that has incoming abnormal/EH edges. 
> This is a classic problem in LCM algorithms.
> See "prune_expressions" in gcse.cc.  I think the moral equivalent for 
> vsetvl generation is to conceptually kill every vsetvl at the entry 
> point to any block that as an incoming abnormal edge.  That should push 
> the insertion point into the block instead of to the incoming edges.

P.S: Apologies for the long email, but I think we agreed on that precedent
already ;-)

OK, it seems vsetvl is pretty much using the same logic as in gcse.cc
As pointed earlier, invalid_opt_bb_p () is indeed indentifying such BBs and
removed from anticipatable and transparent sets for LCM, but doesn't seem to
reflect in LCM output (see details below).

Thx to my colleague Mark Ryan, a resident go expert, we have a simpler go test
now (attached here)

Following is the annotated asm of interest.
 - bb 17 is the one with V insns, needing vsetvl - which LCM tries to "bubble
up" to 15, 16, .. 31
 - bb 38 is the one with unwinder call - note it's dump is code_label/s so it is
only referenced as rtl struct (via eh table, no direct call flow leading to it).

    ...

        ld    s9,176(sp)
        li    s10,0
        j    .L9

        # (code_label 165 164 166 31 7 (nil) [2 uses])
        # (note 166 165 167 31 [bb 31] NOTE_INSN_BASIC_BLOCK)
    .L7:
        addi    s10,s10,1
        beq    s10,s11,.L10

        # (code_label 168 7 73 15 9 (nil) [1 uses])
        # (note 73 168 74 15 [bb 15] NOTE_INSN_BASIC_BLOCK)
    .L9:
        slli    a5,s10,4
        add    a5,s9,a5
        ld    a4,0(a5)

        # (note 246 76 77 16 [bb 16] NOTE_INSN_BASIC_BLOCK)
        sd    a4,32(sp)
        ld    a5,8(a5)

        # (note 247 78 79 17 [bb 17] NOTE_INSN_BASIC_BLOCK) <---

        sd    a5,40(sp)
        vsetivli    zero,2,e64,m1,ta,ma    # 405
        vle64.v    v1,0(s6)            # 361
        addi    a5,sp,112
        vsetivli    zero,2,e64,m1,ta,ma    # 406
        vse64.v    v1,0(a5)            # 362
        beq    s0,zero,.L7
        ld    a1,112(sp)
        ld    a2,120(sp)
        mv    a0,s4
        call    runtime.ifaceE2T2P
        sd    a1,136(sp)
        sd    a1,56(sp)

        # (note 248 91 102 19 [bb 19] NOTE_INSN_BASIC_BLOCK)

        sd    a0,128(sp)
        sd    a0,48(sp)
        andi    a1,a1,0xff
        beq    a1,zero,.L7
    ...
    ...
    ...
        # (note 255 152 156 30 [bb 30] NOTE_INSN_BASIC_BLOCK)

        sd    a0,144(sp)
        sd    a0,80(sp)
        sd    a1,152(sp)
        sd    a1,88(sp)
        ld    a5,0(a0)

        # Another instance of [bb 31] created by later bbro
    .LEHE1:
        addi    s10,s10,1
        bne    s10,s11,.L9
    .L10:
        addi    s1,s1,1
        bne    s1,s2,.L5
        li    a4,0
    ...
    ...
        # (code_label/s 256 347 258 38 15 (nil) [1 uses])
        # (note 258 256 222 38 [bb 38] NOTE_INSN_BASIC_BLOCK)   # culprit EH
    block which leads to EDGE_ABNORMAL
    .L15:
    .LEHB4:
        call    _Unwind_Resume
    .LEHE4:
    .LFE1:
        .section    .gcc_except_table,"a",@progbits
    ...
        .uleb128 .L15-.LFB1
        .uleb128 0
        .uleb128 .LEHB4-.LFB1


We see the following output where LCM is working its way up (read from bottom 
up)

    ;; 19 succs { 20 31 }        # P2 lift up 3 (succ 31 was lift up 2)
    ;; 30 succs { 38 31 }        # P2 lift up 3 (succ 31 was lift up 2)

    ;; 31 succs { 44 32 }        # P2 lift up 2b (succ 44 was succ of 15 which
    was lift up 1)
    ;; 44 succs { 15 }        # P2 lift up 2a (succ 15 was lift up 1)

    ;; 15 succs { 38 16 }        # P2. lift up 1 (succ 16 was lift up 1)

    ;; 16 succs { 38 17 }        # P2. lift up 0 (succ 17 had vsetvl locally 
needed)

    ;; 17 succs { 18 31 }        # P1. VSETVL locally needed


Although I have evidence that bb 16, 17 etc with abnormal edges are being
skipped in LCM phases 2 and 3.
When they are identified, we clear them from Anticipated and Transparent sets.

    Phase 2: Lift up vsetvl info.

      Try lift up 0.

     --- skipping abnormal SUCC edge bb 5 -> bb 38):  --- skipping bb 5):
     --- skipping abnormal SUCC edge bb 6 -> bb 38):  --- skipping bb 6):
     --- skipping abnormal SUCC edge bb 7 -> bb 38):  --- skipping bb 7):
     --- skipping abnormal SUCC edge bb 8 -> bb 38):  --- skipping bb 8):
     --- skipping abnormal SUCC edge bb 9 -> bb 38):  --- skipping bb 9):
     --- skipping abnormal SUCC edge bb 10 -> bb 38): --- skipping bb 10):
     --- skipping abnormal SUCC edge bb 15 -> bb 38):  --- skipping bb 15):   
<--
     --- skipping abnormal SUCC edge bb 16 -> bb 38):  --- skipping bb 16):    
<--
     --- skipping abnormal SUCC edge bb 18 -> bb 38):  --- skipping bb 18):
     --- skipping abnormal SUCC edge bb 20 -> bb 38):  --- skipping bb 20):
     --- skipping abnormal SUCC edge bb 21 -> bb 38):  --- skipping bb 21):
     --- skipping abnormal SUCC edge bb 22 -> bb 38):  --- skipping bb 22):
     --- skipping abnormal SUCC edge bb 23 -> bb 38):  --- skipping bb 23):
     --- skipping abnormal SUCC edge bb 26 -> bb 38):  --- skipping bb 26):
     --- skipping abnormal SUCC edge bb 27 -> bb 38):  --- skipping bb 27):
     --- skipping abnormal SUCC edge bb 28 -> bb 38):  --- skipping bb 28):
     --- skipping abnormal SUCC edge bb 29 -> bb 38):  --- skipping bb 29):
     --- skipping abnormal SUCC edge bb 30 -> bb 38):  --- skipping bb 30):
     --- skipping abnormal PRED edge bb 5 -> bb 38):  --- skipping bb 38):


However we still see lift up using those blocks - the earliest set computed
contained the supposedly elided bbs.

      Try lift up 0.

          earliest:
            Edge(bb 16 -> bb 17): n_bits = 3, set = {1 }

      Try lift up 1.

          earliest:
            Edge(bb 15 -> bb 16): n_bits = 3, set = {1 }

And subsequently the earliest set is used for rest of the algorithm.

Thx,
-Vineet
/* { dg-do compile { target riscv64*-*-* } }  */
/* { dg-options "-O2 -march=rv64gcv -mabi=lp64d" } */

package ast

type as struct {
	bt []struct{}
	an string
}

func bj(a *as) string {
	if b := a.bt; len(a.an) == 1 {
		_ = b[0]
	}
	return a.an
}

func MergePackageFiles(f map[string][]interface{}, g uint) []interface{} {
	bl := make([]string, len(f))
	var bo []interface{}
	bu := make(map[string]int)
	for _, bm := range bl {
		a := f[bm]
		for _, d := range a {
			if g != 0 {
				if a, p := d.(*as); p {
					n := bj(a)
					if j, bp := bu[n]; bp {
						_ = j
					}
				}
			}
		}
	}
	for _, bm := range bl {
		_ = bm
	}
	for _, bm := range bl {
		_ = f[bm]
	}
	return bo
}

Reply via email to