mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Add a pseudo instruction REG_SEQUENCE that takes a list of registers and
sub-register indices and outputs a single super register which is formed from a consecutive sequence of registers. This is used as register allocation / coalescing aid and it is useful to represent instructions that output register pairs / quads. For example, v1024, v1025 = vload <address> where v1024 and v1025 forms a register pair. This really should be modelled as v1024<3>, v1025<4> = vload <address> but it would violate SSA property before register allocation is done. Currently we use insert_subreg to form the super register: v1026 = implicit_def v1027 - insert_subreg v1026, v1024, 3 v1028 = insert_subreg v1027, v1025, 4 ... = use v1024 = use v1028 But this adds pseudo live interval overlap between v1024 and v1025. We can now modeled it as v1024, v1025 = vload <address> v1026 = REG_SEQUENCE v1024, 3, v1025, 4 ... = use v1024 = use v1026 After coalescing, it will be v1026<3>, v1025<4> = vload <address> ... = use v1026<3> = use v1026 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102815 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -473,6 +473,15 @@ def DBG_VALUE : Instruction {
|
|||||||
let Namespace = "TargetOpcode";
|
let Namespace = "TargetOpcode";
|
||||||
let isAsCheapAsAMove = 1;
|
let isAsCheapAsAMove = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def REG_SEQUENCE : Instruction {
|
||||||
|
let OutOperandList = (outs unknown:$dst);
|
||||||
|
let InOperandList = (ins variable_ops);
|
||||||
|
let AsmString = "";
|
||||||
|
let Namespace = "TargetOpcode";
|
||||||
|
let neverHasSideEffects = 1;
|
||||||
|
let isAsCheapAsAMove = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@@ -62,9 +62,17 @@ namespace TargetOpcode {
|
|||||||
/// instructions are insufficient. The actual MachineInstrs to perform
|
/// instructions are insufficient. The actual MachineInstrs to perform
|
||||||
/// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
|
/// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
|
||||||
COPY_TO_REGCLASS = 10,
|
COPY_TO_REGCLASS = 10,
|
||||||
|
|
||||||
/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
|
/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
|
||||||
DBG_VALUE = 11
|
DBG_VALUE = 11,
|
||||||
|
|
||||||
|
/// REG_SEQUENCE - This variadic instruction is used to form a register that
|
||||||
|
/// represent a consecutive sequence of sub-registers. It's used as register
|
||||||
|
/// coalescing / allocation aid and must be eliminated before code emission.
|
||||||
|
/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
|
||||||
|
/// After register coalescing references of v1024 should be replace with
|
||||||
|
/// v1027:3, v1025 with v1027:4, etc.
|
||||||
|
REG_SEQUENCE = 12
|
||||||
};
|
};
|
||||||
} // end namespace TargetOpcode
|
} // end namespace TargetOpcode
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@@ -35,7 +35,8 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
|
|||||||
R->getName() == "IMPLICIT_DEF" ||
|
R->getName() == "IMPLICIT_DEF" ||
|
||||||
R->getName() == "SUBREG_TO_REG" ||
|
R->getName() == "SUBREG_TO_REG" ||
|
||||||
R->getName() == "COPY_TO_REGCLASS" ||
|
R->getName() == "COPY_TO_REGCLASS" ||
|
||||||
R->getName() == "DBG_VALUE") continue;
|
R->getName() == "DBG_VALUE" ||
|
||||||
|
R->getName() == "REG_SEQUENCE") continue;
|
||||||
|
|
||||||
BitsInit *BI = R->getValueAsBitsInit("Inst");
|
BitsInit *BI = R->getValueAsBitsInit("Inst");
|
||||||
|
|
||||||
@@ -113,7 +114,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
|
|||||||
R->getName() == "IMPLICIT_DEF" ||
|
R->getName() == "IMPLICIT_DEF" ||
|
||||||
R->getName() == "SUBREG_TO_REG" ||
|
R->getName() == "SUBREG_TO_REG" ||
|
||||||
R->getName() == "COPY_TO_REGCLASS" ||
|
R->getName() == "COPY_TO_REGCLASS" ||
|
||||||
R->getName() == "DBG_VALUE") {
|
R->getName() == "DBG_VALUE" ||
|
||||||
|
R->getName() == "REG_SEQUENCE") {
|
||||||
o << " 0U,\n";
|
o << " 0U,\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -152,7 +154,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
|
|||||||
InstName == "IMPLICIT_DEF" ||
|
InstName == "IMPLICIT_DEF" ||
|
||||||
InstName == "SUBREG_TO_REG" ||
|
InstName == "SUBREG_TO_REG" ||
|
||||||
InstName == "COPY_TO_REGCLASS" ||
|
InstName == "COPY_TO_REGCLASS" ||
|
||||||
InstName == "DBG_VALUE") continue;
|
InstName == "DBG_VALUE" ||
|
||||||
|
InstName == "REG_SEQUENCE") continue;
|
||||||
|
|
||||||
BitsInit *BI = R->getValueAsBitsInit("Inst");
|
BitsInit *BI = R->getValueAsBitsInit("Inst");
|
||||||
const std::vector<RecordVal> &Vals = R->getValues();
|
const std::vector<RecordVal> &Vals = R->getValues();
|
||||||
|
@@ -326,6 +326,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
|
|||||||
const CodeGenInstruction *COPY_TO_REGCLASS =
|
const CodeGenInstruction *COPY_TO_REGCLASS =
|
||||||
GetInstByName("COPY_TO_REGCLASS", Insts);
|
GetInstByName("COPY_TO_REGCLASS", Insts);
|
||||||
const CodeGenInstruction *DBG_VALUE = GetInstByName("DBG_VALUE", Insts);
|
const CodeGenInstruction *DBG_VALUE = GetInstByName("DBG_VALUE", Insts);
|
||||||
|
const CodeGenInstruction *REG_SEQUENCE = GetInstByName("REG_SEQUENCE", Insts);
|
||||||
|
|
||||||
// Print out the rest of the instructions now.
|
// Print out the rest of the instructions now.
|
||||||
InstrsByEnum.push_back(PHI);
|
InstrsByEnum.push_back(PHI);
|
||||||
@@ -340,6 +341,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
|
|||||||
InstrsByEnum.push_back(SUBREG_TO_REG);
|
InstrsByEnum.push_back(SUBREG_TO_REG);
|
||||||
InstrsByEnum.push_back(COPY_TO_REGCLASS);
|
InstrsByEnum.push_back(COPY_TO_REGCLASS);
|
||||||
InstrsByEnum.push_back(DBG_VALUE);
|
InstrsByEnum.push_back(DBG_VALUE);
|
||||||
|
InstrsByEnum.push_back(REG_SEQUENCE);
|
||||||
|
|
||||||
unsigned EndOfPredefines = InstrsByEnum.size();
|
unsigned EndOfPredefines = InstrsByEnum.size();
|
||||||
|
|
||||||
@@ -357,7 +359,8 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
|
|||||||
CGI != IMPLICIT_DEF &&
|
CGI != IMPLICIT_DEF &&
|
||||||
CGI != SUBREG_TO_REG &&
|
CGI != SUBREG_TO_REG &&
|
||||||
CGI != COPY_TO_REGCLASS &&
|
CGI != COPY_TO_REGCLASS &&
|
||||||
CGI != DBG_VALUE)
|
CGI != DBG_VALUE &&
|
||||||
|
CGI != REG_SEQUENCE)
|
||||||
InstrsByEnum.push_back(CGI);
|
InstrsByEnum.push_back(CGI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user