diff options
author | Evan Cheng <evan.cheng@apple.com> | 2010-05-01 00:28:44 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2010-05-01 00:28:44 +0000 |
commit | b55c8bed9d0f3eaa454a657746d8ec11aae9dea3 (patch) | |
tree | a711f3e3c0ce07662b161f653e4e8b4151d5b1b4 | |
parent | 95140a4cc168bb75a54a434e3e53f9060742dc41 (diff) |
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
-rw-r--r-- | include/llvm/Target/Target.td | 9 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 12 | ||||
-rw-r--r-- | utils/TableGen/CodeEmitterGen.cpp | 9 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 5 |
4 files changed, 29 insertions, 6 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 462c38f03d..8e1cc53236 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -473,6 +473,15 @@ def DBG_VALUE : Instruction { let Namespace = "TargetOpcode"; 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; +} } //===----------------------------------------------------------------------===// diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 48665b7431..c4deaa8fbc 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -62,9 +62,17 @@ namespace TargetOpcode { /// instructions are insufficient. The actual MachineInstrs to perform /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. COPY_TO_REGCLASS = 10, - + /// 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 llvm diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index 1ede4529cd..2a2a4ef63e 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -35,7 +35,8 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { R->getName() == "IMPLICIT_DEF" || R->getName() == "SUBREG_TO_REG" || R->getName() == "COPY_TO_REGCLASS" || - R->getName() == "DBG_VALUE") continue; + R->getName() == "DBG_VALUE" || + R->getName() == "REG_SEQUENCE") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); @@ -113,7 +114,8 @@ void CodeEmitterGen::run(raw_ostream &o) { R->getName() == "IMPLICIT_DEF" || R->getName() == "SUBREG_TO_REG" || R->getName() == "COPY_TO_REGCLASS" || - R->getName() == "DBG_VALUE") { + R->getName() == "DBG_VALUE" || + R->getName() == "REG_SEQUENCE") { o << " 0U,\n"; continue; } @@ -152,7 +154,8 @@ void CodeEmitterGen::run(raw_ostream &o) { InstName == "IMPLICIT_DEF" || InstName == "SUBREG_TO_REG" || InstName == "COPY_TO_REGCLASS" || - InstName == "DBG_VALUE") continue; + InstName == "DBG_VALUE" || + InstName == "REG_SEQUENCE") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector<RecordVal> &Vals = R->getValues(); diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 0392895ba4..1efe2ff080 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -326,6 +326,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const { const CodeGenInstruction *COPY_TO_REGCLASS = GetInstByName("COPY_TO_REGCLASS", 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. InstrsByEnum.push_back(PHI); @@ -340,6 +341,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const { InstrsByEnum.push_back(SUBREG_TO_REG); InstrsByEnum.push_back(COPY_TO_REGCLASS); InstrsByEnum.push_back(DBG_VALUE); + InstrsByEnum.push_back(REG_SEQUENCE); unsigned EndOfPredefines = InstrsByEnum.size(); @@ -357,7 +359,8 @@ void CodeGenTarget::ComputeInstrsByEnum() const { CGI != IMPLICIT_DEF && CGI != SUBREG_TO_REG && CGI != COPY_TO_REGCLASS && - CGI != DBG_VALUE) + CGI != DBG_VALUE && + CGI != REG_SEQUENCE) InstrsByEnum.push_back(CGI); } |