Hi, This is another case where GCSE CPROP propagates a global constant that we don't have exposed in the tree optimizers:
--------------------------- typedef enum { SUCCESS = 1, FAILURE } try; typedef struct { unsigned entry:1; unsigned use_assoc:1; } symbol_attribute; extern try check_conflict (symbol_attribute * attr); extern try gfc_add_entry (symbol_attribute *); extern void foo (void); try gfc_add_entry (symbol_attribute * attr) { if (attr->use_assoc != 0) return FAILURE; if (attr->entry) { foo (); return FAILURE; } return check_conflict (attr); } --------------------------- We notice in this case that check_conflict is a tail call, so we mark it as such (.vars dump): --------------------------- ;; Function gfc_add_entry (gfc_add_entry) gfc_add_entry (attr) { try D.1580; unsigned char D.1578; # BLOCK 0 # PRED: ENTRY [100.0%] (fallthru,exec) D.1578 = BIT_FIELD_REF <*attr, 8, 0>; if ((D.1578 & 2) != 0) goto <L6>; else goto <L1>; # SUCC: 5 [33.0%] (true,exec) 1 [67.0%] (false,exec) # BLOCK 5 # PRED: 0 [33.0%] (true,exec) <L6>:; D.1580 = 2; goto <bb 4> (<L4>); # SUCC: 4 [100.0%] (fallthru) # BLOCK 1 # PRED: 0 [67.0%] (false,exec) <L1>:; if ((D.1578 & 1) != 0) goto <L2>; else goto <L3>; # SUCC: 2 [96.0%] (true,exec) 3 [4.0%] (false,exec) # BLOCK 2 # PRED: 1 [96.0%] (true,exec) <L2>:; foo (); D.1580 = 2; goto <bb 4> (<L4>); # SUCC: 4 [100.0%] (fallthru,exec) # BLOCK 3 # PRED: 1 [4.0%] (false,exec) <L3>:; D.1580 = check_conflict (attr) [tail call]; # SUCC: 4 [100.0%] (fallthru,exec) # BLOCK 4 # PRED: 5 [100.0%] (fallthru) 2 [100.0%] (fallthru,exec) 3 [100.0%] (fallthru,exec) <L4>:; return D.1580; # SUCC: EXIT [100.0%] } --------------------------- Indeed, we succeed in expanding the call to check_conflict as a tail call, so the edge from BLOCK 2 to BLOCK 4 is redirected to the functino exit, and suddenly D.1580 == 2 on all paths to it, and GCSE CPROP propagates this constant. Question is, can we (and do we want to) expose this constant to the tree optimizers? We do not know if the call we marked as a tail call will indeed be expanded as one, so just adding a return at the end of BLOCK 3 may pessimize the code. Maybe we can do it somewhere late in the tree optimizer path, but before the final constant propagation pass? Gr. Steven