blob: 7b1b2d64fcccece53254bc834ff73f45126e7dd5 [file] [log] [blame]
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +00001//=- llvm/CodeGen/DFAPacketizer.cpp - DFA Packetizer for VLIW -*- 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// This class implements a deterministic finite automaton (DFA) based
10// packetizing mechanism for VLIW architectures. It provides APIs to
11// determine whether there exists a legal mapping of instructions to
12// functional unit assignments in a packet. The DFA is auto-generated from
13// the target's Schedule.td file.
14//
15// A DFA consists of 3 major elements: states, inputs, and transitions. For
16// the packetizing mechanism, the input is the set of instruction classes for
17// a target. The state models all possible combinations of functional unit
18// consumption for a given set of instructions in a packet. A transition
19// models the addition of an instruction to a packet. In the DFA constructed
20// by this class, if an instruction can be added to a packet, then a valid
21// transition exists from the corresponding state. Invalid transitions
22// indicate that the instruction cannot be added to the current packet.
23//
24//===----------------------------------------------------------------------===//
25
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +000026#define DEBUG_TYPE "packets"
27
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000028#include "llvm/CodeGen/DFAPacketizer.h"
29#include "llvm/CodeGen/MachineInstr.h"
Andrew Trick7a35fae2012-02-15 18:55:14 +000030#include "llvm/CodeGen/MachineInstrBundle.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000031#include "llvm/CodeGen/ScheduleDAGInstrs.h"
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000032#include "llvm/MC/MCInstrItineraries.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000033#include "llvm/Target/TargetInstrInfo.h"
Krzysztof Parzyszeke4582d42016-08-19 21:12:52 +000034#include "llvm/Support/CommandLine.h"
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +000035
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000036using namespace llvm;
37
Krzysztof Parzyszeke4582d42016-08-19 21:12:52 +000038static cl::opt<unsigned> InstrLimit("dfa-instr-limit", cl::Hidden,
39 cl::init(0), cl::desc("If present, stops packetizing after N instructions"));
40static unsigned InstrCount = 0;
41
Krzysztof Parzyszek6753f332015-11-22 15:20:19 +000042// --------------------------------------------------------------------
43// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp
44
45namespace {
46 DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
47 return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
48 }
49
50 /// Return the DFAInput for an instruction class input vector.
51 /// This function is used in both DFAPacketizer.cpp and in
52 /// DFAPacketizerEmitter.cpp.
53 DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
54 DFAInput InsnInput = 0;
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +000055 assert((InsnClass.size() <= DFA_MAX_RESTERMS) &&
56 "Exceeded maximum number of DFA terms");
Krzysztof Parzyszek6753f332015-11-22 15:20:19 +000057 for (auto U : InsnClass)
58 InsnInput = addDFAFuncUnits(InsnInput, U);
59 return InsnInput;
60 }
61}
62// --------------------------------------------------------------------
63
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +000064DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
65 const DFAStateInput (*SIT)[2],
Sebastian Popac35a4d2011-12-06 17:34:16 +000066 const unsigned *SET):
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000067 InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +000068 DFAStateEntryTable(SET) {
69 // Make sure DFA types are large enough for the number of terms & resources.
Benjamin Kramer3e9a5d32016-05-27 11:36:04 +000070 static_assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <=
71 (8 * sizeof(DFAInput)),
72 "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAInput");
73 static_assert(
74 (DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput)),
75 "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +000076}
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000077
78
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +000079// Read the DFA transition table and update CachedTable.
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000080//
81// Format of the transition tables:
82// DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
83// transitions
84// DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable
85// for the ith state
86//
87void DFAPacketizer::ReadTable(unsigned int state) {
88 unsigned ThisState = DFAStateEntryTable[state];
89 unsigned NextStateInTable = DFAStateEntryTable[state+1];
90 // Early exit in case CachedTable has already contains this
Sebastian Pop9aa61372011-12-06 17:34:11 +000091 // state's transitions.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +000092 if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisState][0])))
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +000093 return;
94
95 for (unsigned i = ThisState; i < NextStateInTable; i++)
96 CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
97 DFAStateInputTable[i][1];
98}
99
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000100
101// Return the DFAInput for an instruction class.
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000102DFAInput DFAPacketizer::getInsnInput(unsigned InsnClass) {
103 // Note: this logic must match that in DFAPacketizerDefs.h for input vectors.
104 DFAInput InsnInput = 0;
105 unsigned i = 0;
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000106 (void)i;
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000107 for (const InstrStage *IS = InstrItins->beginStage(InsnClass),
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000108 *IE = InstrItins->endStage(InsnClass); IS != IE; ++IS) {
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000109 InsnInput = addDFAFuncUnits(InsnInput, IS->getUnits());
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000110 assert((i++ < DFA_MAX_RESTERMS) && "Exceeded maximum number of DFA inputs");
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000111 }
112 return InsnInput;
113}
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000114
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000115
116// Return the DFAInput for an instruction class input vector.
Krzysztof Parzyszek6753f332015-11-22 15:20:19 +0000117DFAInput DFAPacketizer::getInsnInput(const std::vector<unsigned> &InsnClass) {
118 return getDFAInsnInput(InsnClass);
119}
120
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000121
122// Check if the resources occupied by a MCInstrDesc are available in the
123// current state.
Sebastian Popac35a4d2011-12-06 17:34:16 +0000124bool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000125 unsigned InsnClass = MID->getSchedClass();
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000126 DFAInput InsnInput = getInsnInput(InsnClass);
127 UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000128 ReadTable(CurrentState);
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000129 return CachedTable.count(StateTrans) != 0;
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000130}
131
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000132
133// Reserve the resources occupied by a MCInstrDesc and change the current
134// state to reflect that change.
Sebastian Popac35a4d2011-12-06 17:34:16 +0000135void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000136 unsigned InsnClass = MID->getSchedClass();
Krzysztof Parzyszekb4655722015-11-21 20:00:45 +0000137 DFAInput InsnInput = getInsnInput(InsnClass);
138 UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000139 ReadTable(CurrentState);
140 assert(CachedTable.count(StateTrans) != 0);
141 CurrentState = CachedTable[StateTrans];
142}
143
144
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000145// Check if the resources occupied by a machine instruction are available
146// in the current state.
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000147bool DFAPacketizer::canReserveResources(llvm::MachineInstr &MI) {
148 const llvm::MCInstrDesc &MID = MI.getDesc();
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000149 return canReserveResources(&MID);
150}
151
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000152
153// Reserve the resources occupied by a machine instruction and change the
154// current state to reflect that change.
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000155void DFAPacketizer::reserveResources(llvm::MachineInstr &MI) {
156 const llvm::MCInstrDesc &MID = MI.getDesc();
Anshuman Dasgupta08ebdc12011-12-01 21:10:21 +0000157 reserveResources(&MID);
158}
Andrew Trick7a35fae2012-02-15 18:55:14 +0000159
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000160
Sirish Pande94212162012-05-01 21:28:30 +0000161namespace llvm {
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000162// This class extends ScheduleDAGInstrs and overrides the schedule method
163// to build the dependence graph.
Andrew Trick7a35fae2012-02-15 18:55:14 +0000164class DefaultVLIWScheduler : public ScheduleDAGInstrs {
Krzysztof Parzyszekdac71022015-12-14 20:35:13 +0000165private:
166 AliasAnalysis *AA;
Krzysztof Parzyszek1a1d78b2016-03-08 15:33:51 +0000167 /// Ordered list of DAG postprocessing steps.
168 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
Andrew Trick7a35fae2012-02-15 18:55:14 +0000169public:
Krzysztof Parzyszekdac71022015-12-14 20:35:13 +0000170 DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
171 AliasAnalysis *AA);
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000172 // Actual scheduling work.
Craig Topper4584cd52014-03-07 09:26:03 +0000173 void schedule() override;
Krzysztof Parzyszek1a1d78b2016-03-08 15:33:51 +0000174
175 /// DefaultVLIWScheduler takes ownership of the Mutation object.
176 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
177 Mutations.push_back(std::move(Mutation));
178 }
179protected:
180 void postprocessDAG();
Andrew Trick7a35fae2012-02-15 18:55:14 +0000181};
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000182}
Andrew Trick20349b82012-02-15 23:34:15 +0000183
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000184
Alexey Samsonovea0aee62014-08-20 20:57:26 +0000185DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
Krzysztof Parzyszekdac71022015-12-14 20:35:13 +0000186 MachineLoopInfo &MLI,
187 AliasAnalysis *AA)
188 : ScheduleDAGInstrs(MF, &MLI), AA(AA) {
Sirish Pande94212162012-05-01 21:28:30 +0000189 CanHandleTerminators = true;
Andrew Trick7a35fae2012-02-15 18:55:14 +0000190}
191
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000192
Krzysztof Parzyszek1a1d78b2016-03-08 15:33:51 +0000193/// Apply each ScheduleDAGMutation step in order.
194void DefaultVLIWScheduler::postprocessDAG() {
195 for (auto &M : Mutations)
196 M->apply(this);
197}
198
199
Andrew Trick52226d42012-03-07 23:00:49 +0000200void DefaultVLIWScheduler::schedule() {
Andrew Trick7a35fae2012-02-15 18:55:14 +0000201 // Build the scheduling graph.
Krzysztof Parzyszekdac71022015-12-14 20:35:13 +0000202 buildSchedGraph(AA);
Krzysztof Parzyszek1a1d78b2016-03-08 15:33:51 +0000203 postprocessDAG();
Andrew Trick7a35fae2012-02-15 18:55:14 +0000204}
205
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000206
207VLIWPacketizerList::VLIWPacketizerList(MachineFunction &mf,
208 MachineLoopInfo &mli, AliasAnalysis *aa)
209 : MF(mf), TII(mf.getSubtarget().getInstrInfo()), AA(aa) {
Eric Christopher143f02c2014-10-09 01:59:35 +0000210 ResourceTracker = TII->CreateTargetScheduleState(MF.getSubtarget());
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000211 VLIWScheduler = new DefaultVLIWScheduler(MF, mli, AA);
Andrew Trick7a35fae2012-02-15 18:55:14 +0000212}
213
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000214
Andrew Trick7a35fae2012-02-15 18:55:14 +0000215VLIWPacketizerList::~VLIWPacketizerList() {
Sirish Pande94212162012-05-01 21:28:30 +0000216 if (VLIWScheduler)
217 delete VLIWScheduler;
Sirish Pande94212162012-05-01 21:28:30 +0000218 if (ResourceTracker)
219 delete ResourceTracker;
Andrew Trick7a35fae2012-02-15 18:55:14 +0000220}
221
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000222
223// End the current packet, bundle packet instructions and reset DFA state.
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000224void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
225 MachineBasicBlock::iterator MI) {
Krzysztof Parzyszeke4582d42016-08-19 21:12:52 +0000226 DEBUG({
227 if (!CurrentPacketMIs.empty()) {
228 dbgs() << "Finalizing packet:\n";
229 for (MachineInstr *MI : CurrentPacketMIs)
230 dbgs() << " * " << *MI;
231 }
232 });
Andrew Trick7a35fae2012-02-15 18:55:14 +0000233 if (CurrentPacketMIs.size() > 1) {
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000234 MachineInstr &MIFirst = *CurrentPacketMIs.front();
235 finalizeBundle(*MBB, MIFirst.getIterator(), MI.getInstrIterator());
Andrew Trick7a35fae2012-02-15 18:55:14 +0000236 }
237 CurrentPacketMIs.clear();
238 ResourceTracker->clearResources();
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000239 DEBUG(dbgs() << "End packet\n");
Andrew Trick7a35fae2012-02-15 18:55:14 +0000240}
241
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000242
243// Bundle machine instructions into packets.
Andrew Trick7a35fae2012-02-15 18:55:14 +0000244void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
245 MachineBasicBlock::iterator BeginItr,
246 MachineBasicBlock::iterator EndItr) {
Sirish Pande94212162012-05-01 21:28:30 +0000247 assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
248 VLIWScheduler->startBlock(MBB);
Andrew Tricka53e1012013-08-23 17:48:33 +0000249 VLIWScheduler->enterRegion(MBB, BeginItr, EndItr,
250 std::distance(BeginItr, EndItr));
Sirish Pande94212162012-05-01 21:28:30 +0000251 VLIWScheduler->schedule();
Andrew Trick69b42042012-03-07 23:01:09 +0000252
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000253 DEBUG({
254 dbgs() << "Scheduling DAG of the packetize region\n";
255 for (SUnit &SU : VLIWScheduler->SUnits)
256 SU.dumpAll(VLIWScheduler);
257 });
258
Sirish Pande94212162012-05-01 21:28:30 +0000259 // Generate MI -> SU map.
260 MIToSUnit.clear();
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000261 for (SUnit &SU : VLIWScheduler->SUnits)
262 MIToSUnit[SU.getInstr()] = &SU;
Andrew Trick7a35fae2012-02-15 18:55:14 +0000263
Krzysztof Parzyszeke4582d42016-08-19 21:12:52 +0000264 bool LimitPresent = InstrLimit.getPosition();
265
Andrew Trick7a35fae2012-02-15 18:55:14 +0000266 // The main packetizer loop.
267 for (; BeginItr != EndItr; ++BeginItr) {
Krzysztof Parzyszeke4582d42016-08-19 21:12:52 +0000268 if (LimitPresent) {
269 if (InstrCount >= InstrLimit) {
270 EndItr = BeginItr;
271 break;
272 }
273 InstrCount++;
274 }
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000275 MachineInstr &MI = *BeginItr;
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000276 initPacketizerState();
Andrew Trick7a35fae2012-02-15 18:55:14 +0000277
278 // End the current packet if needed.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000279 if (isSoloInstruction(MI)) {
Andrew Trick7a35fae2012-02-15 18:55:14 +0000280 endPacket(MBB, MI);
281 continue;
282 }
283
Sirish Pande94212162012-05-01 21:28:30 +0000284 // Ignore pseudo instructions.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000285 if (ignorePseudoInstruction(MI, MBB))
Sirish Pande94212162012-05-01 21:28:30 +0000286 continue;
287
Duncan P. N. Exon Smith57022872016-02-27 19:09:00 +0000288 SUnit *SUI = MIToSUnit[&MI];
Andrew Trick7a35fae2012-02-15 18:55:14 +0000289 assert(SUI && "Missing SUnit Info!");
290
291 // Ask DFA if machine resource is available for MI.
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000292 DEBUG(dbgs() << "Checking resources for adding MI to packet " << MI);
293
Andrew Trick7a35fae2012-02-15 18:55:14 +0000294 bool ResourceAvail = ResourceTracker->canReserveResources(MI);
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000295 DEBUG({
296 if (ResourceAvail)
297 dbgs() << " Resources are available for adding MI to packet\n";
298 else
299 dbgs() << " Resources NOT available\n";
300 });
Krzysztof Parzyszek2005d7d2015-12-16 16:38:16 +0000301 if (ResourceAvail && shouldAddToPacket(MI)) {
Andrew Trick7a35fae2012-02-15 18:55:14 +0000302 // Dependency check for MI with instructions in CurrentPacketMIs.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000303 for (auto MJ : CurrentPacketMIs) {
Sirish Pande94212162012-05-01 21:28:30 +0000304 SUnit *SUJ = MIToSUnit[MJ];
Andrew Trick7a35fae2012-02-15 18:55:14 +0000305 assert(SUJ && "Missing SUnit Info!");
306
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000307 DEBUG(dbgs() << " Checking against MJ " << *MJ);
Andrew Trick7a35fae2012-02-15 18:55:14 +0000308 // Is it legal to packetize SUI and SUJ together.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000309 if (!isLegalToPacketizeTogether(SUI, SUJ)) {
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000310 DEBUG(dbgs() << " Not legal to add MI, try to prune\n");
Andrew Trick7a35fae2012-02-15 18:55:14 +0000311 // Allow packetization if dependency can be pruned.
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000312 if (!isLegalToPruneDependencies(SUI, SUJ)) {
Andrew Trick7a35fae2012-02-15 18:55:14 +0000313 // End the packet if dependency cannot be pruned.
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000314 DEBUG(dbgs() << " Could not prune dependencies for adding MI\n");
Andrew Trick7a35fae2012-02-15 18:55:14 +0000315 endPacket(MBB, MI);
316 break;
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000317 }
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000318 DEBUG(dbgs() << " Pruned dependence for adding MI\n");
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000319 }
320 }
Andrew Trick7a35fae2012-02-15 18:55:14 +0000321 } else {
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000322 DEBUG(if (ResourceAvail)
323 dbgs() << "Resources are available, but instruction should not be "
324 "added to packet\n " << MI);
Krzysztof Parzyszek2005d7d2015-12-16 16:38:16 +0000325 // End the packet if resource is not available, or if the instruction
326 // shoud not be added to the current packet.
Andrew Trick7a35fae2012-02-15 18:55:14 +0000327 endPacket(MBB, MI);
328 }
329
330 // Add MI to the current packet.
Krzysztof Parzyszek31ceba72016-07-14 19:04:26 +0000331 DEBUG(dbgs() << "* Adding MI to packet " << MI << '\n');
Krzysztof Parzyszekc005e202016-01-14 21:17:04 +0000332 BeginItr = addToPacket(MI);
333 } // For all instructions in the packetization range.
Andrew Trick7a35fae2012-02-15 18:55:14 +0000334
335 // End any packet left behind.
336 endPacket(MBB, EndItr);
Sirish Pande94212162012-05-01 21:28:30 +0000337 VLIWScheduler->exitRegion();
338 VLIWScheduler->finishBlock();
Andrew Trick7a35fae2012-02-15 18:55:14 +0000339}
Krzysztof Parzyszek1a1d78b2016-03-08 15:33:51 +0000340
341
342// Add a DAG mutation object to the ordered list.
343void VLIWPacketizerList::addMutation(
344 std::unique_ptr<ScheduleDAGMutation> Mutation) {
345 VLIWScheduler->addMutation(std::move(Mutation));
346}