If the false value for a select_cc is really simple (has no inputs), evaluate

it in the block.  This codegens:

int %test(bool %c) {
        %retval = select bool %c, int 17, int 1
        ret int %retval
}

as:

_test:
        rlwinm r2, r3, 0, 31, 31
        li r2, 17
        cmpwi cr0, r3, 0
        bne .LBB_test_2 ;
.LBB_test_1:    ;
        li r2, 1
.LBB_test_2:    ;
        or r3, r2, r2
        blr

instead of:

_test:
        rlwinm r2, r3, 0, 31, 31
        li r2, 17
        li r4, 1
        cmpwi cr0, r3, 0
        bne .LBB_test_2 ;
.LBB_test_1:    ;
        or r2, r4, r4
.LBB_test_2:    ;
        or r3, r2, r2
        blr

... which is one fewer instruction.  The savings are more significant for
global address and constantfp nodes.

llvm-svn: 22946
This commit is contained in:
Chris Lattner 2005-08-21 17:41:11 +00:00
parent 7b6b326b2c
commit 0500e362bf
1 changed files with 16 additions and 1 deletions

View File

@ -1675,7 +1675,16 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
// selecting it in the fallthrough basic block rather than here, which
// increases register pressure.
unsigned TrueValue = SelectExpr(N.getOperand(2));
unsigned FalseValue = SelectExpr(N.getOperand(3));
unsigned FalseValue;
// If the false value is simple enough, evaluate it inline in the false
// block.
if (isa<ConstantSDNode>(N.getOperand(3)) ||
isa<ConstantFPSDNode>(N.getOperand(3)) ||
isa<GlobalAddressSDNode>(N.getOperand(3)))
FalseValue = 0;
else
FalseValue = SelectExpr(N.getOperand(3));
unsigned CCReg = SelectCC(N.getOperand(0), N.getOperand(1), CC);
Opc = getBCCForSetCC(CC);
@ -1706,6 +1715,12 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
// %FalseValue = ...
// # fallthrough to sinkMBB
BB = copy0MBB;
// If the false value is simple enough, evaluate it here, to avoid it being
// evaluated on the true edge.
if (FalseValue == 0)
FalseValue = SelectExpr(N.getOperand(3));
// Update machine-CFG edges
BB->addSuccessor(sinkMBB);