@@ -51,10 +51,11 @@ class PseudoLoweringEmitter {
51
51
52
52
SmallVector<PseudoExpansion, 64 > Expansions;
53
53
54
- unsigned addDagOperandMapping (const Record *Rec, const DagInit *Dag,
55
- const CodeGenInstruction &Insn,
56
- IndexedMap<OpData> &OperandMap,
57
- unsigned BaseIdx);
54
+ void addOperandMapping (unsigned MIOpNo, unsigned NumOps, const Record *Rec,
55
+ const DagInit *Dag, unsigned DagIdx,
56
+ const Record *OpRec, IndexedMap<OpData> &OperandMap,
57
+ const StringMap<unsigned > &SourceOperands,
58
+ const CodeGenInstruction &SourceInsn);
58
59
void evaluateExpansion (const Record *Pseudo);
59
60
void emitLoweringEmitter (raw_ostream &o);
60
61
@@ -66,64 +67,67 @@ class PseudoLoweringEmitter {
66
67
};
67
68
} // End anonymous namespace
68
69
69
- // FIXME: This pass currently can only expand a pseudo to a single instruction.
70
- // The pseudo expansion really should take a list of dags, not just
71
- // a single dag, so we can do fancier things.
72
- unsigned PseudoLoweringEmitter::addDagOperandMapping (
73
- const Record *Rec, const DagInit *Dag, const CodeGenInstruction &Insn,
74
- IndexedMap<OpData> &OperandMap, unsigned BaseIdx) {
75
- unsigned OpsAdded = 0 ;
76
- for (unsigned i = 0 , e = Dag->getNumArgs (); i != e; ++i) {
77
- if (const DefInit *DI = dyn_cast<DefInit>(Dag->getArg (i))) {
78
- // Physical register reference. Explicit check for the special case
79
- // "zero_reg" definition.
80
- if (DI->getDef ()->isSubClassOf (" Register" ) ||
81
- DI->getDef ()->getName () == " zero_reg" ) {
82
- auto &Entry = OperandMap[BaseIdx + i];
83
- Entry.Kind = OpData::Reg;
84
- Entry.Data .Reg = DI->getDef ();
85
- ++OpsAdded;
86
- continue ;
87
- }
70
+ void PseudoLoweringEmitter::addOperandMapping (
71
+ unsigned MIOpNo, unsigned NumOps, const Record *Rec, const DagInit *Dag,
72
+ unsigned DagIdx, const Record *OpRec, IndexedMap<OpData> &OperandMap,
73
+ const StringMap<unsigned > &SourceOperands,
74
+ const CodeGenInstruction &SourceInsn) {
75
+ const Init *DagArg = Dag->getArg (DagIdx);
76
+ if (const DefInit *DI = dyn_cast<DefInit>(DagArg)) {
77
+ // Physical register reference. Explicit check for the special case
78
+ // "zero_reg" definition.
79
+ if (DI->getDef ()->isSubClassOf (" Register" ) ||
80
+ DI->getDef ()->getName () == " zero_reg" ) {
81
+ auto &Entry = OperandMap[MIOpNo];
82
+ Entry.Kind = OpData::Reg;
83
+ Entry.Data .Reg = DI->getDef ();
84
+ return ;
85
+ }
88
86
89
- // Normal operands should always have the same type, or we have a
90
- // problem.
91
- // FIXME: We probably shouldn't ever get a non-zero BaseIdx here.
92
- assert (BaseIdx == 0 && " Named subargument in pseudo expansion?!" );
93
- if (DI->getDef () != Insn.Operands [BaseIdx + i].Rec )
94
- PrintFatalError (Rec, " In pseudo instruction '" + Rec->getName () +
95
- " ', operand type '" + DI->getDef ()->getName () +
96
- " ' does not match expansion operand type '" +
97
- Insn.Operands [BaseIdx + i].Rec ->getName () +
98
- " '" );
99
- // Source operand maps to destination operand. The Data element
100
- // will be filled in later, just set the Kind for now. Do it
101
- // for each corresponding MachineInstr operand, not just the first.
102
- for (unsigned I = 0 , E = Insn.Operands [i].MINumOperands ; I != E; ++I)
103
- OperandMap[BaseIdx + i + I].Kind = OpData::Operand;
104
- OpsAdded += Insn.Operands [i].MINumOperands ;
105
- } else if (const IntInit *II = dyn_cast<IntInit>(Dag->getArg (i))) {
106
- auto &Entry = OperandMap[BaseIdx + i];
107
- Entry.Kind = OpData::Imm;
108
- Entry.Data .Imm = II->getValue ();
109
- ++OpsAdded;
110
- } else if (const auto *BI = dyn_cast<BitsInit>(Dag->getArg (i))) {
111
- auto &Entry = OperandMap[BaseIdx + i];
112
- Entry.Kind = OpData::Imm;
113
- Entry.Data .Imm = *BI->convertInitializerToInt ();
114
- ++OpsAdded;
115
- } else if (const DagInit *SubDag = dyn_cast<DagInit>(Dag->getArg (i))) {
116
- // Just add the operands recursively. This is almost certainly
117
- // a constant value for a complex operand (> 1 MI operand).
118
- unsigned NewOps =
119
- addDagOperandMapping (Rec, SubDag, Insn, OperandMap, BaseIdx + i);
120
- OpsAdded += NewOps;
121
- // Since we added more than one, we also need to adjust the base.
122
- BaseIdx += NewOps - 1 ;
123
- } else
124
- llvm_unreachable (" Unhandled pseudo-expansion argument type!" );
125
- }
126
- return OpsAdded;
87
+ if (DI->getDef () != OpRec)
88
+ PrintFatalError (Rec, " In pseudo instruction '" + Rec->getName () +
89
+ " ', operand type '" + DI->getDef ()->getName () +
90
+ " ' does not match expansion operand type '" +
91
+ OpRec->getName () + " '" );
92
+
93
+ StringMap<unsigned >::const_iterator SourceOp =
94
+ SourceOperands.find (Dag->getArgNameStr (DagIdx));
95
+ if (SourceOp == SourceOperands.end ())
96
+ PrintFatalError (Rec, " In pseudo instruction '" + Rec->getName () +
97
+ " ', output operand '" +
98
+ Dag->getArgNameStr (DagIdx) +
99
+ " ' has no matching source operand" );
100
+ const auto &SrcOpnd = SourceInsn.Operands [SourceOp->getValue ()];
101
+ if (NumOps != SrcOpnd.MINumOperands )
102
+ PrintFatalError (
103
+ Rec,
104
+ " In pseudo instruction '" + Rec->getName () + " ', output operand '" +
105
+ OpRec->getName () +
106
+ " ' has a different number of sub operands than source operand '" +
107
+ SrcOpnd.Rec ->getName () + " '" );
108
+
109
+ // Source operand maps to destination operand. Do it for each corresponding
110
+ // MachineInstr operand, not just the first.
111
+ for (unsigned I = 0 , E = NumOps; I != E; ++I) {
112
+ auto &Entry = OperandMap[MIOpNo + I];
113
+ Entry.Kind = OpData::Operand;
114
+ Entry.Data .Operand = SrcOpnd.MIOperandNo + I;
115
+ }
116
+
117
+ LLVM_DEBUG (dbgs () << " " << SourceOp->getValue () << " ==> " << DagIdx
118
+ << " \n " );
119
+ } else if (const auto *II = dyn_cast<IntInit>(DagArg)) {
120
+ assert (NumOps == 1 );
121
+ auto &Entry = OperandMap[MIOpNo];
122
+ Entry.Kind = OpData::Imm;
123
+ Entry.Data .Imm = II->getValue ();
124
+ } else if (const auto *BI = dyn_cast<BitsInit>(DagArg)) {
125
+ assert (NumOps == 1 );
126
+ auto &Entry = OperandMap[MIOpNo];
127
+ Entry.Kind = OpData::Imm;
128
+ Entry.Data .Imm = *BI->convertInitializerToInt ();
129
+ } else
130
+ llvm_unreachable (" Unhandled pseudo-expansion argument type!" );
127
131
}
128
132
129
133
void PseudoLoweringEmitter::evaluateExpansion (const Record *Rec) {
@@ -157,14 +161,6 @@ void PseudoLoweringEmitter::evaluateExpansion(const Record *Rec) {
157
161
" ', result operator '" + Operator->getName () +
158
162
" ' has the wrong number of operands" );
159
163
160
- unsigned NumMIOperands = 0 ;
161
- for (const auto &Op : Insn.Operands )
162
- NumMIOperands += Op.MINumOperands ;
163
- IndexedMap<OpData> OperandMap;
164
- OperandMap.grow (NumMIOperands);
165
-
166
- addDagOperandMapping (Rec, Dag, Insn, OperandMap, 0 );
167
-
168
164
// If there are more operands that weren't in the DAG, they have to
169
165
// be operands that have default values, or we have an error. Currently,
170
166
// Operands that are a subclass of OperandWithDefaultOp have default values.
@@ -180,37 +176,43 @@ void PseudoLoweringEmitter::evaluateExpansion(const Record *Rec) {
180
176
for (const auto &[Idx, SrcOp] : enumerate(SourceInsn.Operands ))
181
177
SourceOperands[SrcOp.Name ] = Idx;
182
178
183
- LLVM_DEBUG (dbgs () << " Operand mapping:\n " );
184
- for (const auto &[Idx, Opnd] : enumerate(Insn.Operands )) {
185
- // We've already handled constant values. Just map instruction operands
186
- // here.
187
- if (OperandMap[Opnd.MIOperandNo ].Kind != OpData::Operand)
188
- continue ;
189
- StringMap<unsigned >::iterator SourceOp =
190
- SourceOperands.find (Dag->getArgNameStr (Idx));
191
- if (SourceOp == SourceOperands.end ())
192
- PrintFatalError (Rec, " In pseudo instruction '" + Rec->getName () +
193
- " ', output operand '" + Dag->getArgNameStr (Idx) +
194
- " ' has no matching source operand" );
195
- const auto &SrcOpnd = SourceInsn.Operands [SourceOp->getValue ()];
196
- if (Opnd.MINumOperands != SrcOpnd.MINumOperands )
197
- PrintFatalError (
198
- Rec,
199
- " In pseudo instruction '" + Rec->getName () + " ', output operand '" +
200
- Opnd.Rec ->getName () +
201
- " ' has a different number of sub operands than source operand '" +
202
- SrcOpnd.Rec ->getName () + " '" );
179
+ unsigned NumMIOperands = 0 ;
180
+ for (const auto &Op : Insn.Operands )
181
+ NumMIOperands += Op.MINumOperands ;
182
+ IndexedMap<OpData> OperandMap;
183
+ OperandMap.grow (NumMIOperands);
203
184
204
- // Map the source operand to the destination operand index for each
205
- // MachineInstr operand.
206
- for (unsigned I = 0 , E = Opnd.MINumOperands ; I != E; ++I)
207
- OperandMap[Opnd.MIOperandNo + I].Data .Operand = SrcOpnd.MIOperandNo + I;
185
+ // FIXME: This pass currently can only expand a pseudo to a single
186
+ // instruction. The pseudo expansion really should take a list of dags, not
187
+ // just a single dag, so we can do fancier things.
188
+ LLVM_DEBUG (dbgs () << " Operand mapping:\n " );
189
+ for (const auto &[Idx, DstOp] : enumerate(Insn.Operands )) {
190
+ unsigned MIOpNo = DstOp.MIOperandNo ;
208
191
209
- LLVM_DEBUG (dbgs () << " " << SourceOp->getValue () << " ==> " << Idx
210
- << " \n " );
192
+ if (const auto *SubDag = dyn_cast<DagInit>(Dag->getArg (Idx))) {
193
+ if (!DstOp.MIOperandInfo || DstOp.MIOperandInfo ->getNumArgs () == 0 )
194
+ PrintFatalError (Rec, " In pseudo instruction '" + Rec->getName () +
195
+ " ', operand '" + DstOp.Rec ->getName () +
196
+ " ' does not have suboperands" );
197
+ if (DstOp.MINumOperands != SubDag->getNumArgs ()) {
198
+ PrintFatalError (
199
+ Rec, " In pseudo instruction '" + Rec->getName () + " ', '" +
200
+ SubDag->getAsString () +
201
+ " ' has wrong number of operands for operand type '" +
202
+ DstOp.Rec ->getName () + " '" );
203
+ }
204
+ for (unsigned I = 0 , E = DstOp.MINumOperands ; I != E; ++I) {
205
+ auto *OpndRec = cast<DefInit>(DstOp.MIOperandInfo ->getArg (I))->getDef ();
206
+ addOperandMapping (MIOpNo + I, 1 , Rec, SubDag, I, OpndRec, OperandMap,
207
+ SourceOperands, SourceInsn);
208
+ }
209
+ } else {
210
+ addOperandMapping (MIOpNo, DstOp.MINumOperands , Rec, Dag, Idx, DstOp.Rec ,
211
+ OperandMap, SourceOperands, SourceInsn);
212
+ }
211
213
}
212
214
213
- Expansions.push_back ( PseudoExpansion ( SourceInsn, Insn, OperandMap) );
215
+ Expansions.emplace_back ( SourceInsn, Insn, OperandMap);
214
216
}
215
217
216
218
void PseudoLoweringEmitter::emitLoweringEmitter (raw_ostream &o) {
0 commit comments