Skip to content

Commit 01541c3

Browse files
committed
Optimize flags.
1 parent 4f149ae commit 01541c3

File tree

4 files changed

+314
-78
lines changed

4 files changed

+314
-78
lines changed

llvm/lib/Target/Z80/GISel/Z80InstructionSelector.cpp

Lines changed: 121 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,17 @@ class Z80InstructionSelector : public InstructionSelector {
7979
Z80::CondCode foldSetCC(MachineInstr &I, MachineIRBuilder &MIB,
8080
MachineRegisterInfo &MRI) const;
8181
Z80::CondCode foldCond(Register CondReg, MachineIRBuilder &MIB,
82-
MachineRegisterInfo &MRI) const;
82+
MachineRegisterInfo &MRI,
83+
Z80::CondCode PreferredCC = Z80::COND_INVALID) const;
8384
bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI) const;
8485
bool selectFunnelShift(MachineInstr &I, MachineRegisterInfo &MRI) const;
85-
bool selectSetCond(MachineInstr &I, MachineRegisterInfo &MRI) const;
86+
bool selectSetCond(unsigned ExtOpc, Register DstReg, Register CondReg,
87+
MachineInstr &I, MachineRegisterInfo &MRI) const;
88+
bool selectSetCond(unsigned ExtOpc, MachineInstr &I,
89+
MachineRegisterInfo &MRI) const {
90+
Register CondReg = I.getOperand(I.getNumExplicitDefs() - 1).getReg();
91+
return selectSetCond(ExtOpc, CondReg, CondReg, I, MRI);
92+
}
8693

8794
bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI) const;
8895
bool selectBrCond(MachineInstr &I, MachineRegisterInfo &MRI) const;
@@ -298,7 +305,7 @@ bool Z80InstructionSelector::select(MachineInstr &I) const {
298305
case TargetOpcode::INLINEASM:
299306
return selectInlineAsm(I, MRI);
300307
case Z80::SetCC:
301-
return selectSetCond(I, MRI);
308+
return selectSetCond(TargetOpcode::G_ZEXT, I, MRI);
302309
}
303310
return true;
304311
}
@@ -361,7 +368,7 @@ bool Z80InstructionSelector::select(MachineInstr &I) const {
361368
case TargetOpcode::G_SSUBO:
362369
case TargetOpcode::G_SSUBE:
363370
case TargetOpcode::G_ICMP:
364-
return selectSetCond(I, MRI);
371+
return selectSetCond(TargetOpcode::G_ANYEXT, I, MRI);
365372
case TargetOpcode::G_BRCOND:
366373
return selectBrCond(I, MRI);
367374
case TargetOpcode::G_BRINDIRECT:
@@ -443,16 +450,18 @@ bool Z80InstructionSelector::selectSExt(MachineInstr &I,
443450
MachineRegisterInfo &MRI) const {
444451
assert(I.getOpcode() == TargetOpcode::G_SEXT && "unexpected instruction");
445452

446-
const Register DstReg = I.getOperand(0).getReg();
447-
const Register SrcReg = I.getOperand(1).getReg();
453+
Register DstReg = I.getOperand(0).getReg();
454+
Register SrcReg = I.getOperand(1).getReg();
448455

449-
const LLT DstTy = MRI.getType(DstReg);
450-
const LLT SrcTy = MRI.getType(SrcReg);
456+
LLT DstTy = MRI.getType(DstReg);
457+
LLT SrcTy = MRI.getType(SrcReg);
451458

452459
if (SrcTy != LLT::scalar(1))
453460
return false;
454461

455-
MachineIRBuilder MIB(I);
462+
if (MRI.hasOneUse(SrcReg) &&
463+
selectSetCond(I.getOpcode(), DstReg, SrcReg, I, MRI))
464+
return true;
456465

457466
unsigned FillOpc;
458467
Register FillReg;
@@ -477,6 +486,7 @@ bool Z80InstructionSelector::selectSExt(MachineInstr &I,
477486
return false;
478487
}
479488

489+
MachineIRBuilder MIB(I);
480490
auto Rotate = MIB.buildInstr(Z80::RRC8r, {LLT::scalar(8)}, {SrcReg});
481491
if (!constrainSelectedInstRegOperands(*Rotate, TII, TRI, RBI))
482492
return false;
@@ -504,8 +514,11 @@ bool Z80InstructionSelector::selectZExt(MachineInstr &I,
504514
if (MRI.getType(SrcReg) != LLT::scalar(1))
505515
return false;
506516

507-
MachineIRBuilder MIB(I);
517+
if (MRI.hasOneUse(SrcReg) &&
518+
selectSetCond(I.getOpcode(), DstReg, SrcReg, I, MRI))
519+
return true;
508520

521+
MachineIRBuilder MIB(I);
509522
auto CopyToA = MIB.buildCopy(Z80::A, SrcReg);
510523
if (!constrainSelectedInstRegOperands(*CopyToA, TII, TRI, RBI))
511524
return false;
@@ -527,11 +540,16 @@ bool Z80InstructionSelector::selectAnyExt(MachineInstr &I,
527540
MachineRegisterInfo &MRI) const {
528541
assert(I.getOpcode() == TargetOpcode::G_ANYEXT && "unexpected instruction");
529542

543+
const Register SrcReg = I.getOperand(1).getReg();
530544
const Register DstReg = I.getOperand(0).getReg();
545+
546+
if (MRI.getType(SrcReg) == LLT::scalar(1) && MRI.hasOneUse(SrcReg) &&
547+
selectSetCond(I.getOpcode(), DstReg, SrcReg, I, MRI))
548+
return true;
549+
531550
const TargetRegisterClass *DstRC = getRegClass(DstReg, MRI);
532551
const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
533552

534-
const Register SrcReg = I.getOperand(1).getReg();
535553
const TargetRegisterClass *SrcRC = getRegClass(SrcReg, MRI);
536554
unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
537555

@@ -1365,9 +1383,10 @@ Z80InstructionSelector::foldSetCC(MachineInstr &I, MachineIRBuilder &MIB,
13651383
return Z80::CondCode(I.getOperand(1).getImm());
13661384
}
13671385

1368-
Z80::CondCode Z80InstructionSelector::foldCond(Register CondReg,
1369-
MachineIRBuilder &MIB,
1370-
MachineRegisterInfo &MRI) const {
1386+
Z80::CondCode
1387+
Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
1388+
MachineRegisterInfo &MRI,
1389+
Z80::CondCode PreferredCC) const {
13711390
assert(MRI.getType(CondReg) == LLT::scalar(1) && "Expected s1 condition");
13721391

13731392
bool OppositeCond = false;
@@ -1396,6 +1415,7 @@ Z80::CondCode Z80InstructionSelector::foldCond(Register CondReg,
13961415

13971416
Z80::CondCode CC = Z80::COND_INVALID;
13981417
if (CondDef) {
1418+
// TODO: prefer PreferredCC
13991419
switch (CondDef->getOpcode()) {
14001420
case TargetOpcode::G_ICMP:
14011421
CC = foldCompare(*CondDef, MIB, MRI);
@@ -1431,6 +1451,11 @@ Z80::CondCode Z80InstructionSelector::foldCond(Register CondReg,
14311451
if (OppositeCond)
14321452
CC = Z80::GetOppositeBranchCondition(CC);
14331453

1454+
if (CC == Z80::GetOppositeBranchCondition(PreferredCC)) {
1455+
MIB.buildInstr(Z80::CCF);
1456+
CC = PreferredCC;
1457+
}
1458+
14341459
return CC;
14351460
}
14361461

@@ -1531,27 +1556,97 @@ bool Z80InstructionSelector::selectFunnelShift(MachineInstr &I,
15311556
return true;
15321557
}
15331558

1534-
bool Z80InstructionSelector::selectSetCond(MachineInstr &I,
1559+
bool Z80InstructionSelector::selectSetCond(unsigned ExtOpc, Register DstReg,
1560+
Register CondReg, MachineInstr &I,
15351561
MachineRegisterInfo &MRI) const {
1536-
Register CondReg = I.getOperand(I.getNumExplicitDefs() - 1).getReg();
1537-
assert(MRI.getType(CondReg) == LLT::scalar(1) && "Expected s1 condition");
1562+
LLT DstTy = MRI.getType(DstReg);
1563+
1564+
unsigned SetOpc, SelectOpc, IncOpc, FillOpc;
1565+
Register FillReg;
1566+
const TargetRegisterClass *DstRC;
1567+
switch (DstTy.getSizeInBits()) {
1568+
case 1:
1569+
case 8:
1570+
SetOpc = Z80::LD8ri;
1571+
SelectOpc = Z80::Select8;
1572+
IncOpc = Z80::INC8r;
1573+
FillOpc = Z80::SBC8ar;
1574+
FillReg = Z80::A;
1575+
DstRC = &Z80::R8RegClass;
1576+
break;
1577+
case 16:
1578+
SetOpc = Z80::LD16ri;
1579+
SelectOpc = Z80::Select16;
1580+
IncOpc = Z80::INC16r;
1581+
FillOpc = Z80::SBC16aa;
1582+
FillReg = Z80::HL;
1583+
DstRC = &Z80::R16RegClass;
1584+
break;
1585+
case 24:
1586+
if (!STI.is24Bit())
1587+
return false;
1588+
SetOpc = Z80::LD24ri;
1589+
SelectOpc = Z80::Select24;
1590+
IncOpc = Z80::INC24r;
1591+
FillOpc = Z80::SBC24aa;
1592+
FillReg = Z80::UHL;
1593+
DstRC = &Z80::R24RegClass;
1594+
break;
1595+
default:
1596+
return false;
1597+
}
15381598

15391599
MachineIRBuilder MIB(I);
1540-
Z80::CondCode CC = foldCond(CondReg, MIB, MRI);
1600+
Z80::CondCode DirectCC =
1601+
ExtOpc == TargetOpcode::G_ZEXT ? Z80::COND_NC : Z80::COND_C;
1602+
Z80::CondCode CC = foldCond(CondReg, MIB, MRI, DirectCC);
15411603
if (CC == Z80::COND_INVALID)
15421604
return false;
15431605

1544-
if (MRI.reg_empty(CondReg))
1606+
if (MRI.reg_empty(DstReg)) {
1607+
I.eraseFromParent();
15451608
return true;
1609+
}
1610+
1611+
if (CC != DirectCC) {
1612+
auto TrueI = MIB.buildInstr(
1613+
SetOpc, {DstTy}, {int64_t(ExtOpc == TargetOpcode::G_ZEXT ? 1 : -1)});
1614+
auto FalseI = MIB.buildInstr(SetOpc, {DstTy}, {int64_t(0)});
1615+
auto SelectI =
1616+
MIB.buildInstr(SelectOpc, {DstReg}, {TrueI, FalseI, int64_t(CC)});
1617+
if (!constrainSelectedInstRegOperands(*FalseI, TII, TRI, RBI) ||
1618+
!constrainSelectedInstRegOperands(*TrueI, TII, TRI, RBI) ||
1619+
!constrainSelectedInstRegOperands(*SelectI, TII, TRI, RBI))
1620+
return false;
1621+
} else {
1622+
Register UndefReg = Z80::NoRegister;
1623+
if (FillOpc == Z80::SBC8ar) {
1624+
auto CopyUndefI = MIB.buildCopy(DstTy, FillReg);
1625+
CopyUndefI->findRegisterUseOperand(FillReg)->setIsUndef();
1626+
UndefReg = CopyUndefI.getReg(0);
1627+
if (!RBI.constrainGenericRegister(UndefReg, *DstRC, MRI))
1628+
return false;
1629+
}
1630+
auto FillI = MIB.buildInstr(FillOpc);
1631+
FillI->findRegisterUseOperand(FillReg)->setIsUndef();
1632+
if (UndefReg)
1633+
FillI.addUse(UndefReg, RegState::Undef);
1634+
if (!constrainSelectedInstRegOperands(*FillI, TII, TRI, RBI))
1635+
return false;
1636+
if (ExtOpc == TargetOpcode::G_ZEXT) {
1637+
Register TmpReg = MIB.buildCopy(DstTy, FillReg).getReg(0);
1638+
if (!RBI.constrainGenericRegister(TmpReg, *DstRC, MRI))
1639+
return false;
1640+
auto IncI = MIB.buildInstr(IncOpc, {DstReg}, {TmpReg});
1641+
if (!constrainSelectedInstRegOperands(*IncI, TII, TRI, RBI))
1642+
return false;
1643+
} else if (!RBI.constrainGenericRegister(
1644+
MIB.buildCopy(DstReg, FillReg).getReg(0), *DstRC, MRI))
1645+
return false;
1646+
}
15461647

1547-
auto TrueI = MIB.buildInstr(Z80::LD8ri, {LLT::scalar(8)}, {int64_t(1)});
1548-
auto FalseI = MIB.buildInstr(Z80::LD8ri, {LLT::scalar(8)}, {int64_t(0)});
1549-
auto SelectI =
1550-
MIB.buildInstr(Z80::Select8, {CondReg}, {TrueI, FalseI, int64_t(CC)});
15511648
I.eraseFromParent();
1552-
return constrainSelectedInstRegOperands(*FalseI, TII, TRI, RBI) &&
1553-
constrainSelectedInstRegOperands(*TrueI, TII, TRI, RBI) &&
1554-
constrainSelectedInstRegOperands(*SelectI, TII, TRI, RBI);
1649+
return true;
15551650
}
15561651

15571652
bool Z80InstructionSelector::selectSelect(MachineInstr &I,

llvm/lib/Target/Z80/Z80ISelLowering.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,24 @@ Z80TargetLowering::EmitLoweredCmp0(MachineInstr &MI,
396396
MachineBasicBlock *
397397
Z80TargetLowering::EmitLoweredSelect(MachineInstr &MI,
398398
MachineBasicBlock *BB) const {
399+
MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();
399400
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
400401
DebugLoc DL = MI.getDebugLoc();
401402

403+
Register FalseReg, TrueReg;
404+
int CCIdx;
405+
if (MI.getOpcode() == Z80::SetCC) {
406+
FalseReg = MRI.createVirtualRegister(&Z80::R8RegClass);
407+
BuildMI(BB, DL, TII->get(Z80::LD8ri), FalseReg).addImm(0);
408+
TrueReg = MRI.createVirtualRegister(&Z80::R8RegClass);
409+
BuildMI(BB, DL, TII->get(Z80::LD8ri), TrueReg).addImm(1);
410+
CCIdx = 1;
411+
} else {
412+
FalseReg = MI.getOperand(1).getReg();
413+
TrueReg = MI.getOperand(2).getReg();
414+
CCIdx = 3;
415+
}
416+
402417
// To "insert" a SELECT_CC instruction, we actually have to insert the
403418
// diamond control-flow pattern. The incoming instruction knows the
404419
// destination vreg to set, the condition code register to branch on, the
@@ -429,7 +444,7 @@ Z80TargetLowering::EmitLoweredSelect(MachineInstr &MI,
429444
BB->addSuccessor(copy1MBB);
430445

431446
BuildMI(BB, DL, TII->get(Z80::JQCC)).addMBB(copy1MBB)
432-
.addImm(MI.getOperand(3).getImm());
447+
.add(MI.getOperand(CCIdx));
433448

434449
// copy0MBB:
435450
// %TrueVal = ...
@@ -443,10 +458,8 @@ Z80TargetLowering::EmitLoweredSelect(MachineInstr &MI,
443458
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
444459
// ...
445460
BB = copy1MBB;
446-
BuildMI(*BB, BB->begin(), DL, TII->get(Z80::PHI),
447-
MI.getOperand(0).getReg())
448-
.addReg(MI.getOperand(1).getReg()).addMBB(thisMBB)
449-
.addReg(MI.getOperand(2).getReg()).addMBB(copy0MBB);
461+
BuildMI(*BB, BB->begin(), DL, TII->get(Z80::PHI), MI.getOperand(0).getReg())
462+
.addReg(FalseReg).addMBB(thisMBB).addReg(TrueReg).addMBB(copy0MBB);
450463

451464
MI.eraseFromParent(); // The pseudo instruction is gone now.
452465
LLVM_DEBUG(F->dump());

llvm/lib/Target/Z80/Z80InstrInfo.td

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,12 @@ let Defs = [SPL], Uses = [AF, SPL], mayStore = 1 in
609609
def PUSH24AF : I24<NoPre, 0xF5, "push", "\taf", "",
610610
(outs), (ins), [(Z80push AF)]>;
611611

612-
let isReMaterializable = 1, Defs = [F] in {
613-
def RCF : P;
614-
def SCF : I<NoPre, 0x37, "scf">;
612+
let Defs = [F] in {
613+
let isReMaterializable = 1 in {
614+
def RCF : P;
615+
def SCF : I<NoPre, 0x37, "scf">;
616+
}
617+
let Uses = [F] in
615618
def CCF : I<NoPre, 0x3F, "ccf">;
616619
}
617620

0 commit comments

Comments
 (0)