1 //===--------------------- InstrBuilder.cpp ---------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file implements the InstrBuilder interface.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/MCA/InstrBuilder.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/WithColor.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 #define DEBUG_TYPE "llvm-mca"
24 
25 namespace llvm {
26 namespace mca {
27 
28 InstrBuilder::InstrBuilder(const llvm::MCSubtargetInfo &sti,
29                            const llvm::MCInstrInfo &mcii,
30                            const llvm::MCRegisterInfo &mri,
31                            const llvm::MCInstrAnalysis *mcia)
32     : STI(sti), MCII(mcii), MRI(mri), MCIA(mcia), FirstCallInst(true),
33       FirstReturnInst(true) {
34   computeProcResourceMasks(STI.getSchedModel(), ProcResourceMasks);
35 }
36 
37 static void initializeUsedResources(InstrDesc &ID,
38                                     const MCSchedClassDesc &SCDesc,
39                                     const MCSubtargetInfo &STI,
40                                     ArrayRef<uint64_t> ProcResourceMasks) {
41   const MCSchedModel &SM = STI.getSchedModel();
42 
43   // Populate resources consumed.
44   using ResourcePlusCycles = std::pair<uint64_t, ResourceUsage>;
45   std::vector<ResourcePlusCycles> Worklist;
46 
47   // Track cycles contributed by resources that are in a "Super" relationship.
48   // This is required if we want to correctly match the behavior of method
49   // SubtargetEmitter::ExpandProcResource() in Tablegen. When computing the set
50   // of "consumed" processor resources and resource cycles, the logic in
51   // ExpandProcResource() doesn't update the number of resource cycles
52   // contributed by a "Super" resource to a group.
53   // We need to take this into account when we find that a processor resource is
54   // part of a group, and it is also used as the "Super" of other resources.
55   // This map stores the number of cycles contributed by sub-resources that are
56   // part of a "Super" resource. The key value is the "Super" resource mask ID.
57   DenseMap<uint64_t, unsigned> SuperResources;
58 
59   unsigned NumProcResources = SM.getNumProcResourceKinds();
60   APInt Buffers(NumProcResources, 0);
61 
62   bool AllInOrderResources = true;
63   bool AnyDispatchHazards = false;
64   for (unsigned I = 0, E = SCDesc.NumWriteProcResEntries; I < E; ++I) {
65     const MCWriteProcResEntry *PRE = STI.getWriteProcResBegin(&SCDesc) + I;
66     const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx);
67     uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx];
68     if (PR.BufferSize < 0) {
69       AllInOrderResources = false;
70     } else {
71       Buffers.setBit(PRE->ProcResourceIdx);
72       AnyDispatchHazards |= (PR.BufferSize == 0);
73       AllInOrderResources &= (PR.BufferSize <= 1);
74     }
75 
76     CycleSegment RCy(0, PRE->Cycles, false);
77     Worklist.emplace_back(ResourcePlusCycles(Mask, ResourceUsage(RCy)));
78     if (PR.SuperIdx) {
79       uint64_t Super = ProcResourceMasks[PR.SuperIdx];
80       SuperResources[Super] += PRE->Cycles;
81     }
82   }
83 
84   ID.MustIssueImmediately = AllInOrderResources && AnyDispatchHazards;
85 
86   // Sort elements by mask popcount, so that we prioritize resource units over
87   // resource groups, and smaller groups over larger groups.
88   sort(Worklist, [](const ResourcePlusCycles &A, const ResourcePlusCycles &B) {
89     unsigned popcntA = countPopulation(A.first);
90     unsigned popcntB = countPopulation(B.first);
91     if (popcntA < popcntB)
92       return true;
93     if (popcntA > popcntB)
94       return false;
95     return A.first < B.first;
96   });
97 
98   uint64_t UsedResourceUnits = 0;
99 
100   // Remove cycles contributed by smaller resources.
101   for (unsigned I = 0, E = Worklist.size(); I < E; ++I) {
102     ResourcePlusCycles &A = Worklist[I];
103     if (!A.second.size()) {
104       A.second.NumUnits = 0;
105       A.second.setReserved();
106       ID.Resources.emplace_back(A);
107       continue;
108     }
109 
110     ID.Resources.emplace_back(A);
111     uint64_t NormalizedMask = A.first;
112     if (countPopulation(A.first) == 1) {
113       UsedResourceUnits |= A.first;
114     } else {
115       // Remove the leading 1 from the resource group mask.
116       NormalizedMask ^= PowerOf2Floor(NormalizedMask);
117     }
118 
119     for (unsigned J = I + 1; J < E; ++J) {
120       ResourcePlusCycles &B = Worklist[J];
121       if ((NormalizedMask & B.first) == NormalizedMask) {
122         B.second.CS.subtract(A.second.size() - SuperResources[A.first]);
123         if (countPopulation(B.first) > 1)
124           B.second.NumUnits++;
125       }
126     }
127   }
128 
129   // A SchedWrite may specify a number of cycles in which a resource group
130   // is reserved. For example (on target x86; cpu Haswell):
131   //
132   //  SchedWriteRes<[HWPort0, HWPort1, HWPort01]> {
133   //    let ResourceCycles = [2, 2, 3];
134   //  }
135   //
136   // This means:
137   // Resource units HWPort0 and HWPort1 are both used for 2cy.
138   // Resource group HWPort01 is the union of HWPort0 and HWPort1.
139   // Since this write touches both HWPort0 and HWPort1 for 2cy, HWPort01
140   // will not be usable for 2 entire cycles from instruction issue.
141   //
142   // On top of those 2cy, SchedWriteRes explicitly specifies an extra latency
143   // of 3 cycles for HWPort01. This tool assumes that the 3cy latency is an
144   // extra delay on top of the 2 cycles latency.
145   // During those extra cycles, HWPort01 is not usable by other instructions.
146   for (ResourcePlusCycles &RPC : ID.Resources) {
147     if (countPopulation(RPC.first) > 1 && !RPC.second.isReserved()) {
148       // Remove the leading 1 from the resource group mask.
149       uint64_t Mask = RPC.first ^ PowerOf2Floor(RPC.first);
150       if ((Mask & UsedResourceUnits) == Mask)
151         RPC.second.setReserved();
152     }
153   }
154 
155   // Identify extra buffers that are consumed through super resources.
156   for (const std::pair<uint64_t, unsigned> &SR : SuperResources) {
157     for (unsigned I = 1, E = NumProcResources; I < E; ++I) {
158       const MCProcResourceDesc &PR = *SM.getProcResource(I);
159       if (PR.BufferSize == -1)
160         continue;
161 
162       uint64_t Mask = ProcResourceMasks[I];
163       if (Mask != SR.first && ((Mask & SR.first) == SR.first))
164         Buffers.setBit(I);
165     }
166   }
167 
168   // Now set the buffers.
169   if (unsigned NumBuffers = Buffers.countPopulation()) {
170     ID.Buffers.resize(NumBuffers);
171     for (unsigned I = 0, E = NumProcResources; I < E && NumBuffers; ++I) {
172       if (Buffers[I]) {
173         --NumBuffers;
174         ID.Buffers[NumBuffers] = ProcResourceMasks[I];
175       }
176     }
177   }
178 
179   LLVM_DEBUG({
180     for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
181       dbgs() << "\t\tMask=" << R.first << ", cy=" << R.second.size() << '\n';
182     for (const uint64_t R : ID.Buffers)
183       dbgs() << "\t\tBuffer Mask=" << R << '\n';
184   });
185 }
186 
187 static void computeMaxLatency(InstrDesc &ID, const MCInstrDesc &MCDesc,
188                               const MCSchedClassDesc &SCDesc,
189                               const MCSubtargetInfo &STI) {
190   if (MCDesc.isCall()) {
191     // We cannot estimate how long this call will take.
192     // Artificially set an arbitrarily high latency (100cy).
193     ID.MaxLatency = 100U;
194     return;
195   }
196 
197   int Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
198   // If latency is unknown, then conservatively assume a MaxLatency of 100cy.
199   ID.MaxLatency = Latency < 0 ? 100U : static_cast<unsigned>(Latency);
200 }
201 
202 static Error verifyOperands(const MCInstrDesc &MCDesc, const MCInst &MCI) {
203   // Count register definitions, and skip non register operands in the process.
204   unsigned I, E;
205   unsigned NumExplicitDefs = MCDesc.getNumDefs();
206   for (I = 0, E = MCI.getNumOperands(); NumExplicitDefs && I < E; ++I) {
207     const MCOperand &Op = MCI.getOperand(I);
208     if (Op.isReg())
209       --NumExplicitDefs;
210   }
211 
212   if (NumExplicitDefs) {
213     return make_error<InstructionError<MCInst>>(
214         "Expected more register operand definitions.", MCI);
215   }
216 
217   if (MCDesc.hasOptionalDef()) {
218     // Always assume that the optional definition is the last operand.
219     const MCOperand &Op = MCI.getOperand(MCDesc.getNumOperands() - 1);
220     if (I == MCI.getNumOperands() || !Op.isReg()) {
221       std::string Message =
222           "expected a register operand for an optional definition. Instruction "
223           "has not been correctly analyzed.";
224       return make_error<InstructionError<MCInst>>(Message, MCI);
225     }
226   }
227 
228   return ErrorSuccess();
229 }
230 
231 void InstrBuilder::populateWrites(InstrDesc &ID, const MCInst &MCI,
232                                   unsigned SchedClassID) {
233   const MCInstrDesc &MCDesc = MCII.get(MCI.getOpcode());
234   const MCSchedModel &SM = STI.getSchedModel();
235   const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
236 
237   // Assumptions made by this algorithm:
238   //  1. The number of explicit and implicit register definitions in a MCInst
239   //     matches the number of explicit and implicit definitions according to
240   //     the opcode descriptor (MCInstrDesc).
241   //  2. Uses start at index #(MCDesc.getNumDefs()).
242   //  3. There can only be a single optional register definition, an it is
243   //     always the last operand of the sequence (excluding extra operands
244   //     contributed by variadic opcodes).
245   //
246   // These assumptions work quite well for most out-of-order in-tree targets
247   // like x86. This is mainly because the vast majority of instructions is
248   // expanded to MCInst using a straightforward lowering logic that preserves
249   // the ordering of the operands.
250   //
251   // About assumption 1.
252   // The algorithm allows non-register operands between register operand
253   // definitions. This helps to handle some special ARM instructions with
254   // implicit operand increment (-mtriple=armv7):
255   //
256   // vld1.32  {d18, d19}, [r1]!  @ <MCInst #1463 VLD1q32wb_fixed
257   //                             @  <MCOperand Reg:59>
258   //                             @  <MCOperand Imm:0>     (!!)
259   //                             @  <MCOperand Reg:67>
260   //                             @  <MCOperand Imm:0>
261   //                             @  <MCOperand Imm:14>
262   //                             @  <MCOperand Reg:0>>
263   //
264   // MCDesc reports:
265   //  6 explicit operands.
266   //  1 optional definition
267   //  2 explicit definitions (!!)
268   //
269   // The presence of an 'Imm' operand between the two register definitions
270   // breaks the assumption that "register definitions are always at the
271   // beginning of the operand sequence".
272   //
273   // To workaround this issue, this algorithm ignores (i.e. skips) any
274   // non-register operands between register definitions.  The optional
275   // definition is still at index #(NumOperands-1).
276   //
277   // According to assumption 2. register reads start at #(NumExplicitDefs-1).
278   // That means, register R1 from the example is both read and written.
279   unsigned NumExplicitDefs = MCDesc.getNumDefs();
280   unsigned NumImplicitDefs = MCDesc.getNumImplicitDefs();
281   unsigned NumWriteLatencyEntries = SCDesc.NumWriteLatencyEntries;
282   unsigned TotalDefs = NumExplicitDefs + NumImplicitDefs;
283   if (MCDesc.hasOptionalDef())
284     TotalDefs++;
285 
286   unsigned NumVariadicOps = MCI.getNumOperands() - MCDesc.getNumOperands();
287   ID.Writes.resize(TotalDefs + NumVariadicOps);
288   // Iterate over the operands list, and skip non-register operands.
289   // The first NumExplictDefs register operands are expected to be register
290   // definitions.
291   unsigned CurrentDef = 0;
292   unsigned i = 0;
293   for (; i < MCI.getNumOperands() && CurrentDef < NumExplicitDefs; ++i) {
294     const MCOperand &Op = MCI.getOperand(i);
295     if (!Op.isReg())
296       continue;
297 
298     WriteDescriptor &Write = ID.Writes[CurrentDef];
299     Write.OpIndex = i;
300     if (CurrentDef < NumWriteLatencyEntries) {
301       const MCWriteLatencyEntry &WLE =
302           *STI.getWriteLatencyEntry(&SCDesc, CurrentDef);
303       // Conservatively default to MaxLatency.
304       Write.Latency =
305           WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles);
306       Write.SClassOrWriteResourceID = WLE.WriteResourceID;
307     } else {
308       // Assign a default latency for this write.
309       Write.Latency = ID.MaxLatency;
310       Write.SClassOrWriteResourceID = 0;
311     }
312     Write.IsOptionalDef = false;
313     LLVM_DEBUG({
314       dbgs() << "\t\t[Def]    OpIdx=" << Write.OpIndex
315              << ", Latency=" << Write.Latency
316              << ", WriteResourceID=" << Write.SClassOrWriteResourceID << '\n';
317     });
318     CurrentDef++;
319   }
320 
321   assert(CurrentDef == NumExplicitDefs &&
322          "Expected more register operand definitions.");
323   for (CurrentDef = 0; CurrentDef < NumImplicitDefs; ++CurrentDef) {
324     unsigned Index = NumExplicitDefs + CurrentDef;
325     WriteDescriptor &Write = ID.Writes[Index];
326     Write.OpIndex = ~CurrentDef;
327     Write.RegisterID = MCDesc.getImplicitDefs()[CurrentDef];
328     if (Index < NumWriteLatencyEntries) {
329       const MCWriteLatencyEntry &WLE =
330           *STI.getWriteLatencyEntry(&SCDesc, Index);
331       // Conservatively default to MaxLatency.
332       Write.Latency =
333           WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles);
334       Write.SClassOrWriteResourceID = WLE.WriteResourceID;
335     } else {
336       // Assign a default latency for this write.
337       Write.Latency = ID.MaxLatency;
338       Write.SClassOrWriteResourceID = 0;
339     }
340 
341     Write.IsOptionalDef = false;
342     assert(Write.RegisterID != 0 && "Expected a valid phys register!");
343     LLVM_DEBUG({
344       dbgs() << "\t\t[Def][I] OpIdx=" << ~Write.OpIndex
345              << ", PhysReg=" << MRI.getName(Write.RegisterID)
346              << ", Latency=" << Write.Latency
347              << ", WriteResourceID=" << Write.SClassOrWriteResourceID << '\n';
348     });
349   }
350 
351   if (MCDesc.hasOptionalDef()) {
352     WriteDescriptor &Write = ID.Writes[NumExplicitDefs + NumImplicitDefs];
353     Write.OpIndex = MCDesc.getNumOperands() - 1;
354     // Assign a default latency for this write.
355     Write.Latency = ID.MaxLatency;
356     Write.SClassOrWriteResourceID = 0;
357     Write.IsOptionalDef = true;
358     LLVM_DEBUG({
359       dbgs() << "\t\t[Def][O] OpIdx=" << Write.OpIndex
360              << ", Latency=" << Write.Latency
361              << ", WriteResourceID=" << Write.SClassOrWriteResourceID << '\n';
362     });
363   }
364 
365   if (!NumVariadicOps)
366     return;
367 
368   // FIXME: if an instruction opcode is flagged 'mayStore', and it has no
369   // "unmodeledSideEffects', then this logic optimistically assumes that any
370   // extra register operands in the variadic sequence is not a register
371   // definition.
372   //
373   // Otherwise, we conservatively assume that any register operand from the
374   // variadic sequence is both a register read and a register write.
375   bool AssumeUsesOnly = MCDesc.mayStore() && !MCDesc.mayLoad() &&
376                         !MCDesc.hasUnmodeledSideEffects();
377   CurrentDef = NumExplicitDefs + NumImplicitDefs + MCDesc.hasOptionalDef();
378   for (unsigned I = 0, OpIndex = MCDesc.getNumOperands();
379        I < NumVariadicOps && !AssumeUsesOnly; ++I, ++OpIndex) {
380     const MCOperand &Op = MCI.getOperand(OpIndex);
381     if (!Op.isReg())
382       continue;
383 
384     WriteDescriptor &Write = ID.Writes[CurrentDef];
385     Write.OpIndex = OpIndex;
386     // Assign a default latency for this write.
387     Write.Latency = ID.MaxLatency;
388     Write.SClassOrWriteResourceID = 0;
389     Write.IsOptionalDef = false;
390     ++CurrentDef;
391     LLVM_DEBUG({
392       dbgs() << "\t\t[Def][V] OpIdx=" << Write.OpIndex
393              << ", Latency=" << Write.Latency
394              << ", WriteResourceID=" << Write.SClassOrWriteResourceID << '\n';
395     });
396   }
397 
398   ID.Writes.resize(CurrentDef);
399 }
400 
401 void InstrBuilder::populateReads(InstrDesc &ID, const MCInst &MCI,
402                                  unsigned SchedClassID) {
403   const MCInstrDesc &MCDesc = MCII.get(MCI.getOpcode());
404   unsigned NumExplicitUses = MCDesc.getNumOperands() - MCDesc.getNumDefs();
405   unsigned NumImplicitUses = MCDesc.getNumImplicitUses();
406   // Remove the optional definition.
407   if (MCDesc.hasOptionalDef())
408     --NumExplicitUses;
409   unsigned NumVariadicOps = MCI.getNumOperands() - MCDesc.getNumOperands();
410   unsigned TotalUses = NumExplicitUses + NumImplicitUses + NumVariadicOps;
411   ID.Reads.resize(TotalUses);
412   unsigned CurrentUse = 0;
413   for (unsigned I = 0, OpIndex = MCDesc.getNumDefs(); I < NumExplicitUses;
414        ++I, ++OpIndex) {
415     const MCOperand &Op = MCI.getOperand(OpIndex);
416     if (!Op.isReg())
417       continue;
418 
419     ReadDescriptor &Read = ID.Reads[CurrentUse];
420     Read.OpIndex = OpIndex;
421     Read.UseIndex = I;
422     Read.SchedClassID = SchedClassID;
423     ++CurrentUse;
424     LLVM_DEBUG(dbgs() << "\t\t[Use]    OpIdx=" << Read.OpIndex
425                       << ", UseIndex=" << Read.UseIndex << '\n');
426   }
427 
428   // For the purpose of ReadAdvance, implicit uses come directly after explicit
429   // uses. The "UseIndex" must be updated according to that implicit layout.
430   for (unsigned I = 0; I < NumImplicitUses; ++I) {
431     ReadDescriptor &Read = ID.Reads[CurrentUse + I];
432     Read.OpIndex = ~I;
433     Read.UseIndex = NumExplicitUses + I;
434     Read.RegisterID = MCDesc.getImplicitUses()[I];
435     Read.SchedClassID = SchedClassID;
436     LLVM_DEBUG(dbgs() << "\t\t[Use][I] OpIdx=" << ~Read.OpIndex
437                       << ", UseIndex=" << Read.UseIndex << ", RegisterID="
438                       << MRI.getName(Read.RegisterID) << '\n');
439   }
440 
441   CurrentUse += NumImplicitUses;
442 
443   // FIXME: If an instruction opcode is marked as 'mayLoad', and it has no
444   // "unmodeledSideEffects", then this logic optimistically assumes that any
445   // extra register operands in the variadic sequence are not register
446   // definition.
447 
448   bool AssumeDefsOnly = !MCDesc.mayStore() && MCDesc.mayLoad() &&
449                         !MCDesc.hasUnmodeledSideEffects();
450   for (unsigned I = 0, OpIndex = MCDesc.getNumOperands();
451        I < NumVariadicOps && !AssumeDefsOnly; ++I, ++OpIndex) {
452     const MCOperand &Op = MCI.getOperand(OpIndex);
453     if (!Op.isReg())
454       continue;
455 
456     ReadDescriptor &Read = ID.Reads[CurrentUse];
457     Read.OpIndex = OpIndex;
458     Read.UseIndex = NumExplicitUses + NumImplicitUses + I;
459     Read.SchedClassID = SchedClassID;
460     ++CurrentUse;
461     LLVM_DEBUG(dbgs() << "\t\t[Use][V] OpIdx=" << Read.OpIndex
462                       << ", UseIndex=" << Read.UseIndex << '\n');
463   }
464 
465   ID.Reads.resize(CurrentUse);
466 }
467 
468 Error InstrBuilder::verifyInstrDesc(const InstrDesc &ID,
469                                     const MCInst &MCI) const {
470   if (ID.NumMicroOps != 0)
471     return ErrorSuccess();
472 
473   bool UsesMemory = ID.MayLoad || ID.MayStore;
474   bool UsesBuffers = !ID.Buffers.empty();
475   bool UsesResources = !ID.Resources.empty();
476   if (!UsesMemory && !UsesBuffers && !UsesResources)
477     return ErrorSuccess();
478 
479   StringRef Message;
480   if (UsesMemory) {
481     Message = "found an inconsistent instruction that decodes "
482               "into zero opcodes and that consumes load/store "
483               "unit resources.";
484   } else {
485     Message = "found an inconsistent instruction that decodes "
486               "to zero opcodes and that consumes scheduler "
487               "resources.";
488   }
489 
490   return make_error<InstructionError<MCInst>>(Message, MCI);
491 }
492 
493 Expected<const InstrDesc &>
494 InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
495   assert(STI.getSchedModel().hasInstrSchedModel() &&
496          "Itineraries are not yet supported!");
497 
498   // Obtain the instruction descriptor from the opcode.
499   unsigned short Opcode = MCI.getOpcode();
500   const MCInstrDesc &MCDesc = MCII.get(Opcode);
501   const MCSchedModel &SM = STI.getSchedModel();
502 
503   // Then obtain the scheduling class information from the instruction.
504   unsigned SchedClassID = MCDesc.getSchedClass();
505   bool IsVariant = SM.getSchedClassDesc(SchedClassID)->isVariant();
506 
507   // Try to solve variant scheduling classes.
508   if (IsVariant) {
509     unsigned CPUID = SM.getProcessorID();
510     while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
511       SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &MCI, CPUID);
512 
513     if (!SchedClassID) {
514       return make_error<InstructionError<MCInst>>(
515           "unable to resolve scheduling class for write variant.", MCI);
516     }
517   }
518 
519   // Check if this instruction is supported. Otherwise, report an error.
520   const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
521   if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) {
522     return make_error<InstructionError<MCInst>>(
523         "found an unsupported instruction in the input assembly sequence.",
524         MCI);
525   }
526 
527   // Create a new empty descriptor.
528   std::unique_ptr<InstrDesc> ID = llvm::make_unique<InstrDesc>();
529   ID->NumMicroOps = SCDesc.NumMicroOps;
530 
531   if (MCDesc.isCall() && FirstCallInst) {
532     // We don't correctly model calls.
533     WithColor::warning() << "found a call in the input assembly sequence.\n";
534     WithColor::note() << "call instructions are not correctly modeled. "
535                       << "Assume a latency of 100cy.\n";
536     FirstCallInst = false;
537   }
538 
539   if (MCDesc.isReturn() && FirstReturnInst) {
540     WithColor::warning() << "found a return instruction in the input"
541                          << " assembly sequence.\n";
542     WithColor::note() << "program counter updates are ignored.\n";
543     FirstReturnInst = false;
544   }
545 
546   ID->MayLoad = MCDesc.mayLoad();
547   ID->MayStore = MCDesc.mayStore();
548   ID->HasSideEffects = MCDesc.hasUnmodeledSideEffects();
549   ID->BeginGroup = SCDesc.BeginGroup;
550   ID->EndGroup = SCDesc.EndGroup;
551 
552   initializeUsedResources(*ID, SCDesc, STI, ProcResourceMasks);
553   computeMaxLatency(*ID, MCDesc, SCDesc, STI);
554 
555   if (Error Err = verifyOperands(MCDesc, MCI))
556     return std::move(Err);
557 
558   populateWrites(*ID, MCI, SchedClassID);
559   populateReads(*ID, MCI, SchedClassID);
560 
561 #ifndef NDEBUG
562   ID->Name = MCII.getName(Opcode);
563 #endif
564   LLVM_DEBUG(dbgs() << "\t\tMaxLatency=" << ID->MaxLatency << '\n');
565   LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
566 
567   // Sanity check on the instruction descriptor.
568   if (Error Err = verifyInstrDesc(*ID, MCI))
569     return std::move(Err);
570 
571   // Now add the new descriptor.
572   SchedClassID = MCDesc.getSchedClass();
573   bool IsVariadic = MCDesc.isVariadic();
574   if (!IsVariadic && !IsVariant) {
575     Descriptors[MCI.getOpcode()] = std::move(ID);
576     return *Descriptors[MCI.getOpcode()];
577   }
578 
579   VariantDescriptors[&MCI] = std::move(ID);
580   return *VariantDescriptors[&MCI];
581 }
582 
583 Expected<const InstrDesc &>
584 InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) {
585   if (Descriptors.find_as(MCI.getOpcode()) != Descriptors.end())
586     return *Descriptors[MCI.getOpcode()];
587 
588   if (VariantDescriptors.find(&MCI) != VariantDescriptors.end())
589     return *VariantDescriptors[&MCI];
590 
591   return createInstrDescImpl(MCI);
592 }
593 
594 Expected<std::unique_ptr<Instruction>>
595 InstrBuilder::createInstruction(const MCInst &MCI) {
596   Expected<const InstrDesc &> DescOrErr = getOrCreateInstrDesc(MCI);
597   if (!DescOrErr)
598     return DescOrErr.takeError();
599   const InstrDesc &D = *DescOrErr;
600   std::unique_ptr<Instruction> NewIS = llvm::make_unique<Instruction>(D);
601 
602   // Check if this is a dependency breaking instruction.
603   APInt Mask;
604 
605   bool IsZeroIdiom = false;
606   bool IsDepBreaking = false;
607   if (MCIA) {
608     unsigned ProcID = STI.getSchedModel().getProcessorID();
609     IsZeroIdiom = MCIA->isZeroIdiom(MCI, Mask, ProcID);
610     IsDepBreaking =
611         IsZeroIdiom || MCIA->isDependencyBreaking(MCI, Mask, ProcID);
612     if (MCIA->isOptimizableRegisterMove(MCI, ProcID))
613       NewIS->setOptimizableMove();
614   }
615 
616   // Initialize Reads first.
617   for (const ReadDescriptor &RD : D.Reads) {
618     int RegID = -1;
619     if (!RD.isImplicitRead()) {
620       // explicit read.
621       const MCOperand &Op = MCI.getOperand(RD.OpIndex);
622       // Skip non-register operands.
623       if (!Op.isReg())
624         continue;
625       RegID = Op.getReg();
626     } else {
627       // Implicit read.
628       RegID = RD.RegisterID;
629     }
630 
631     // Skip invalid register operands.
632     if (!RegID)
633       continue;
634 
635     // Okay, this is a register operand. Create a ReadState for it.
636     assert(RegID > 0 && "Invalid register ID found!");
637     NewIS->getUses().emplace_back(RD, RegID);
638     ReadState &RS = NewIS->getUses().back();
639 
640     if (IsDepBreaking) {
641       // A mask of all zeroes means: explicit input operands are not
642       // independent.
643       if (Mask.isNullValue()) {
644         if (!RD.isImplicitRead())
645           RS.setIndependentFromDef();
646       } else {
647         // Check if this register operand is independent according to `Mask`.
648         // Note that Mask may not have enough bits to describe all explicit and
649         // implicit input operands. If this register operand doesn't have a
650         // corresponding bit in Mask, then conservatively assume that it is
651         // dependent.
652         if (Mask.getBitWidth() > RD.UseIndex) {
653           // Okay. This map describe register use `RD.UseIndex`.
654           if (Mask[RD.UseIndex])
655             RS.setIndependentFromDef();
656         }
657       }
658     }
659   }
660 
661   // Early exit if there are no writes.
662   if (D.Writes.empty())
663     return std::move(NewIS);
664 
665   // Track register writes that implicitly clear the upper portion of the
666   // underlying super-registers using an APInt.
667   APInt WriteMask(D.Writes.size(), 0);
668 
669   // Now query the MCInstrAnalysis object to obtain information about which
670   // register writes implicitly clear the upper portion of a super-register.
671   if (MCIA)
672     MCIA->clearsSuperRegisters(MRI, MCI, WriteMask);
673 
674   // Initialize writes.
675   unsigned WriteIndex = 0;
676   for (const WriteDescriptor &WD : D.Writes) {
677     unsigned RegID = WD.isImplicitWrite() ? WD.RegisterID
678                                           : MCI.getOperand(WD.OpIndex).getReg();
679     // Check if this is a optional definition that references NoReg.
680     if (WD.IsOptionalDef && !RegID) {
681       ++WriteIndex;
682       continue;
683     }
684 
685     assert(RegID && "Expected a valid register ID!");
686     NewIS->getDefs().emplace_back(WD, RegID,
687                                   /* ClearsSuperRegs */ WriteMask[WriteIndex],
688                                   /* WritesZero */ IsZeroIdiom);
689     ++WriteIndex;
690   }
691 
692   return std::move(NewIS);
693 }
694 } // namespace mca
695 } // namespace llvm
696