Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/IceInst.h

Issue 656123003: Subzero: Class definition cleanup. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Changes for Karl Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceInstX8632.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares the Inst class and its target-independent 10 // This file declares the Inst class and its target-independent
(...skipping 17 matching lines...) Expand all
28 // We need a list of everything that should be validated, and tests 28 // We need a list of everything that should be validated, and tests
29 // for each. 29 // for each.
30 30
31 namespace Ice { 31 namespace Ice {
32 32
33 // Base instruction class for ICE. Inst has two subclasses: 33 // Base instruction class for ICE. Inst has two subclasses:
34 // InstHighLevel and InstTarget. High-level ICE instructions inherit 34 // InstHighLevel and InstTarget. High-level ICE instructions inherit
35 // from InstHighLevel, and low-level (target-specific) ICE 35 // from InstHighLevel, and low-level (target-specific) ICE
36 // instructions inherit from InstTarget. 36 // instructions inherit from InstTarget.
37 class Inst { 37 class Inst {
38 Inst(const Inst &) = delete;
39 Inst &operator=(const Inst &) = delete;
40
38 public: 41 public:
39 enum InstKind { 42 enum InstKind {
40 // Arbitrary (alphabetical) order, except put Unreachable first. 43 // Arbitrary (alphabetical) order, except put Unreachable first.
41 Unreachable, 44 Unreachable,
42 Alloca, 45 Alloca,
43 Arithmetic, 46 Arithmetic,
44 Assign, // not part of LLVM/PNaCl bitcode 47 Assign, // not part of LLVM/PNaCl bitcode
45 Br, 48 Br,
46 Call, 49 Call,
47 Cast, 50 Cast,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 // instruction. An instruction can have an arbitrary number of 165 // instruction. An instruction can have an arbitrary number of
163 // source operands (e.g. a call instruction), and each source 166 // source operands (e.g. a call instruction), and each source
164 // operand can contain 0 or 1 Variable (and target-specific operands 167 // operand can contain 0 or 1 Variable (and target-specific operands
165 // could contain more than 1 Variable). All the variables in an 168 // could contain more than 1 Variable). All the variables in an
166 // instruction are conceptually flattened and each variable is 169 // instruction are conceptually flattened and each variable is
167 // mapped to one bit position of the LiveRangesEnded bit vector. 170 // mapped to one bit position of the LiveRangesEnded bit vector.
168 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are 171 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are
169 // tracked this way. 172 // tracked this way.
170 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry 173 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry
171 LREndedBits LiveRangesEnded; 174 LREndedBits LiveRangesEnded;
172
173 private:
174 Inst(const Inst &) = delete;
175 Inst &operator=(const Inst &) = delete;
176 }; 175 };
177 176
178 class InstHighLevel : public Inst { 177 class InstHighLevel : public Inst {
179 InstHighLevel(const InstHighLevel &) = delete; 178 InstHighLevel(const InstHighLevel &) = delete;
180 InstHighLevel &operator=(const InstHighLevel &) = delete; 179 InstHighLevel &operator=(const InstHighLevel &) = delete;
181 180
182 protected: 181 protected:
183 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 182 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
184 : Inst(Func, Kind, MaxSrcs, Dest) {} 183 : Inst(Func, Kind, MaxSrcs, Dest) {}
185 void emit(const Cfg * /*Func*/) const override { 184 void emit(const Cfg * /*Func*/) const override {
186 llvm_unreachable("emit() called on a non-lowered instruction"); 185 llvm_unreachable("emit() called on a non-lowered instruction");
187 } 186 }
188 void emitIAS(const Cfg * /*Func*/) const override { 187 void emitIAS(const Cfg * /*Func*/) const override {
189 llvm_unreachable("emitIAS() called on a non-lowered instruction"); 188 llvm_unreachable("emitIAS() called on a non-lowered instruction");
190 } 189 }
191 ~InstHighLevel() override {} 190 ~InstHighLevel() override {}
192 }; 191 };
193 192
194 // Alloca instruction. This captures the size in bytes as getSrc(0), 193 // Alloca instruction. This captures the size in bytes as getSrc(0),
195 // and the required alignment in bytes. The alignment must be either 194 // and the required alignment in bytes. The alignment must be either
196 // 0 (no alignment required) or a power of 2. 195 // 0 (no alignment required) or a power of 2.
197 class InstAlloca : public InstHighLevel { 196 class InstAlloca : public InstHighLevel {
197 InstAlloca(const InstAlloca &) = delete;
198 InstAlloca &operator=(const InstAlloca &) = delete;
199
198 public: 200 public:
199 static InstAlloca *create(Cfg *Func, Operand *ByteCount, 201 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
200 uint32_t AlignInBytes, Variable *Dest) { 202 uint32_t AlignInBytes, Variable *Dest) {
201 return new (Func->allocateInst<InstAlloca>()) 203 return new (Func->allocateInst<InstAlloca>())
202 InstAlloca(Func, ByteCount, AlignInBytes, Dest); 204 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
203 } 205 }
204 uint32_t getAlignInBytes() const { return AlignInBytes; } 206 uint32_t getAlignInBytes() const { return AlignInBytes; }
205 Operand *getSizeInBytes() const { return getSrc(0); } 207 Operand *getSizeInBytes() const { return getSrc(0); }
206 void dump(const Cfg *Func) const override; 208 void dump(const Cfg *Func) const override;
207 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } 209 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
208 210
209 private: 211 private:
210 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, 212 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
211 Variable *Dest); 213 Variable *Dest);
212 InstAlloca(const InstAlloca &) = delete;
213 InstAlloca &operator=(const InstAlloca &) = delete;
214 ~InstAlloca() override {} 214 ~InstAlloca() override {}
215 const uint32_t AlignInBytes; 215 const uint32_t AlignInBytes;
216 }; 216 };
217 217
218 // Binary arithmetic instruction. The source operands are captured in 218 // Binary arithmetic instruction. The source operands are captured in
219 // getSrc(0) and getSrc(1). 219 // getSrc(0) and getSrc(1).
220 class InstArithmetic : public InstHighLevel { 220 class InstArithmetic : public InstHighLevel {
221 InstArithmetic(const InstArithmetic &) = delete;
222 InstArithmetic &operator=(const InstArithmetic &) = delete;
223
221 public: 224 public:
222 enum OpKind { 225 enum OpKind {
223 #define X(tag, str, commutative) tag, 226 #define X(tag, str, commutative) tag,
224 ICEINSTARITHMETIC_TABLE 227 ICEINSTARITHMETIC_TABLE
225 #undef X 228 #undef X
226 _num 229 _num
227 }; 230 };
228 231
229 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest, 232 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
230 Operand *Source1, Operand *Source2) { 233 Operand *Source1, Operand *Source2) {
231 return new (Func->allocateInst<InstArithmetic>()) 234 return new (Func->allocateInst<InstArithmetic>())
232 InstArithmetic(Func, Op, Dest, Source1, Source2); 235 InstArithmetic(Func, Op, Dest, Source1, Source2);
233 } 236 }
234 OpKind getOp() const { return Op; } 237 OpKind getOp() const { return Op; }
235 static const char *getOpName(OpKind Op); 238 static const char *getOpName(OpKind Op);
236 bool isCommutative() const; 239 bool isCommutative() const;
237 void dump(const Cfg *Func) const override; 240 void dump(const Cfg *Func) const override;
238 static bool classof(const Inst *Inst) { 241 static bool classof(const Inst *Inst) {
239 return Inst->getKind() == Arithmetic; 242 return Inst->getKind() == Arithmetic;
240 } 243 }
241 244
242 private: 245 private:
243 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1, 246 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
244 Operand *Source2); 247 Operand *Source2);
245 InstArithmetic(const InstArithmetic &) = delete;
246 InstArithmetic &operator=(const InstArithmetic &) = delete;
247 ~InstArithmetic() override {} 248 ~InstArithmetic() override {}
248 249
249 const OpKind Op; 250 const OpKind Op;
250 }; 251 };
251 252
252 // Assignment instruction. The source operand is captured in 253 // Assignment instruction. The source operand is captured in
253 // getSrc(0). This is not part of the LLVM bitcode, but is a useful 254 // getSrc(0). This is not part of the LLVM bitcode, but is a useful
254 // abstraction for some of the lowering. E.g., if Phi instruction 255 // abstraction for some of the lowering. E.g., if Phi instruction
255 // lowering happens before target lowering, or for representing an 256 // lowering happens before target lowering, or for representing an
256 // Inttoptr instruction, or as an intermediate step for lowering a 257 // Inttoptr instruction, or as an intermediate step for lowering a
257 // Load instruction. 258 // Load instruction.
258 class InstAssign : public InstHighLevel { 259 class InstAssign : public InstHighLevel {
260 InstAssign(const InstAssign &) = delete;
261 InstAssign &operator=(const InstAssign &) = delete;
262
259 public: 263 public:
260 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { 264 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
261 return new (Func->allocateInst<InstAssign>()) 265 return new (Func->allocateInst<InstAssign>())
262 InstAssign(Func, Dest, Source); 266 InstAssign(Func, Dest, Source);
263 } 267 }
264 bool isSimpleAssign() const override { return true; } 268 bool isSimpleAssign() const override { return true; }
265 void dump(const Cfg *Func) const override; 269 void dump(const Cfg *Func) const override;
266 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } 270 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
267 271
268 private: 272 private:
269 InstAssign(Cfg *Func, Variable *Dest, Operand *Source); 273 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
270 InstAssign(const InstAssign &) = delete;
271 InstAssign &operator=(const InstAssign &) = delete;
272 ~InstAssign() override {} 274 ~InstAssign() override {}
273 }; 275 };
274 276
275 // Branch instruction. This represents both conditional and 277 // Branch instruction. This represents both conditional and
276 // unconditional branches. 278 // unconditional branches.
277 class InstBr : public InstHighLevel { 279 class InstBr : public InstHighLevel {
280 InstBr(const InstBr &) = delete;
281 InstBr &operator=(const InstBr &) = delete;
282
278 public: 283 public:
279 // Create a conditional branch. If TargetTrue==TargetFalse, it is 284 // Create a conditional branch. If TargetTrue==TargetFalse, it is
280 // optimized to an unconditional branch. 285 // optimized to an unconditional branch.
281 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, 286 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
282 CfgNode *TargetFalse) { 287 CfgNode *TargetFalse) {
283 return new (Func->allocateInst<InstBr>()) 288 return new (Func->allocateInst<InstBr>())
284 InstBr(Func, Source, TargetTrue, TargetFalse); 289 InstBr(Func, Source, TargetTrue, TargetFalse);
285 } 290 }
286 // Create an unconditional branch. 291 // Create an unconditional branch.
287 static InstBr *create(Cfg *Func, CfgNode *Target) { 292 static InstBr *create(Cfg *Func, CfgNode *Target) {
(...skipping 12 matching lines...) Expand all
300 } 305 }
301 NodeList getTerminatorEdges() const override; 306 NodeList getTerminatorEdges() const override;
302 void dump(const Cfg *Func) const override; 307 void dump(const Cfg *Func) const override;
303 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } 308 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
304 309
305 private: 310 private:
306 // Conditional branch 311 // Conditional branch
307 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); 312 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
308 // Unconditional branch 313 // Unconditional branch
309 InstBr(Cfg *Func, CfgNode *Target); 314 InstBr(Cfg *Func, CfgNode *Target);
310 InstBr(const InstBr &) = delete;
311 InstBr &operator=(const InstBr &) = delete;
312 ~InstBr() override {} 315 ~InstBr() override {}
313 316
314 CfgNode *const TargetFalse; // Doubles as unconditional branch target 317 CfgNode *const TargetFalse; // Doubles as unconditional branch target
315 CfgNode *const TargetTrue; // NULL if unconditional branch 318 CfgNode *const TargetTrue; // NULL if unconditional branch
316 }; 319 };
317 320
318 // Call instruction. The call target is captured as getSrc(0), and 321 // Call instruction. The call target is captured as getSrc(0), and
319 // arg I is captured as getSrc(I+1). 322 // arg I is captured as getSrc(I+1).
320 class InstCall : public InstHighLevel { 323 class InstCall : public InstHighLevel {
324 InstCall(const InstCall &) = delete;
325 InstCall &operator=(const InstCall &) = delete;
326
321 public: 327 public:
322 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, 328 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
323 Operand *CallTarget, bool HasTailCall) { 329 Operand *CallTarget, bool HasTailCall) {
324 // Set HasSideEffects to true so that the call instruction can't be 330 // Set HasSideEffects to true so that the call instruction can't be
325 // dead-code eliminated. IntrinsicCalls can override this if the 331 // dead-code eliminated. IntrinsicCalls can override this if the
326 // particular intrinsic is deletable and has no side-effects. 332 // particular intrinsic is deletable and has no side-effects.
327 const bool HasSideEffects = true; 333 const bool HasSideEffects = true;
328 const InstKind Kind = Inst::Call; 334 const InstKind Kind = Inst::Call;
329 return new (Func->allocateInst<InstCall>()) InstCall( 335 return new (Func->allocateInst<InstCall>()) InstCall(
330 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind); 336 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
(...skipping 11 matching lines...) Expand all
342 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, 348 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
343 bool HasTailCall, bool HasSideEff, InstKind Kind) 349 bool HasTailCall, bool HasSideEff, InstKind Kind)
344 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) { 350 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
345 HasSideEffects = HasSideEff; 351 HasSideEffects = HasSideEff;
346 addSource(CallTarget); 352 addSource(CallTarget);
347 } 353 }
348 ~InstCall() override {} 354 ~InstCall() override {}
349 355
350 private: 356 private:
351 bool HasTailCall; 357 bool HasTailCall;
352 InstCall(const InstCall &) = delete;
353 InstCall &operator=(const InstCall &) = delete;
354 }; 358 };
355 359
356 // Cast instruction (a.k.a. conversion operation). 360 // Cast instruction (a.k.a. conversion operation).
357 class InstCast : public InstHighLevel { 361 class InstCast : public InstHighLevel {
362 InstCast(const InstCast &) = delete;
363 InstCast &operator=(const InstCast &) = delete;
364
358 public: 365 public:
359 enum OpKind { 366 enum OpKind {
360 #define X(tag, str) tag, 367 #define X(tag, str) tag,
361 ICEINSTCAST_TABLE 368 ICEINSTCAST_TABLE
362 #undef X 369 #undef X
363 _num 370 _num
364 }; 371 };
365 372
366 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, 373 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
367 Operand *Source) { 374 Operand *Source) {
368 return new (Func->allocateInst<InstCast>()) 375 return new (Func->allocateInst<InstCast>())
369 InstCast(Func, CastKind, Dest, Source); 376 InstCast(Func, CastKind, Dest, Source);
370 } 377 }
371 OpKind getCastKind() const { return CastKind; } 378 OpKind getCastKind() const { return CastKind; }
372 void dump(const Cfg *Func) const override; 379 void dump(const Cfg *Func) const override;
373 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } 380 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
374 381
375 private: 382 private:
376 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); 383 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
377 InstCast(const InstCast &) = delete;
378 InstCast &operator=(const InstCast &) = delete;
379 ~InstCast() override {} 384 ~InstCast() override {}
380 const OpKind CastKind; 385 const OpKind CastKind;
381 }; 386 };
382 387
383 // ExtractElement instruction. 388 // ExtractElement instruction.
384 class InstExtractElement : public InstHighLevel { 389 class InstExtractElement : public InstHighLevel {
390 InstExtractElement(const InstExtractElement &) = delete;
391 InstExtractElement &operator=(const InstExtractElement &) = delete;
392
385 public: 393 public:
386 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 394 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
387 Operand *Source2) { 395 Operand *Source2) {
388 return new (Func->allocateInst<InstExtractElement>()) 396 return new (Func->allocateInst<InstExtractElement>())
389 InstExtractElement(Func, Dest, Source1, Source2); 397 InstExtractElement(Func, Dest, Source1, Source2);
390 } 398 }
391 399
392 void dump(const Cfg *Func) const override; 400 void dump(const Cfg *Func) const override;
393 static bool classof(const Inst *Inst) { 401 static bool classof(const Inst *Inst) {
394 return Inst->getKind() == ExtractElement; 402 return Inst->getKind() == ExtractElement;
395 } 403 }
396 404
397 private: 405 private:
398 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, 406 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
399 Operand *Source2); 407 Operand *Source2);
400 InstExtractElement(const InstExtractElement &) = delete;
401 InstExtractElement &operator=(const InstExtractElement &) = delete;
402 ~InstExtractElement() override {} 408 ~InstExtractElement() override {}
403 }; 409 };
404 410
405 // Floating-point comparison instruction. The source operands are 411 // Floating-point comparison instruction. The source operands are
406 // captured in getSrc(0) and getSrc(1). 412 // captured in getSrc(0) and getSrc(1).
407 class InstFcmp : public InstHighLevel { 413 class InstFcmp : public InstHighLevel {
414 InstFcmp(const InstFcmp &) = delete;
415 InstFcmp &operator=(const InstFcmp &) = delete;
416
408 public: 417 public:
409 enum FCond { 418 enum FCond {
410 #define X(tag, str) tag, 419 #define X(tag, str) tag,
411 ICEINSTFCMP_TABLE 420 ICEINSTFCMP_TABLE
412 #undef X 421 #undef X
413 _num 422 _num
414 }; 423 };
415 424
416 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, 425 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
417 Operand *Source1, Operand *Source2) { 426 Operand *Source1, Operand *Source2) {
418 return new (Func->allocateInst<InstFcmp>()) 427 return new (Func->allocateInst<InstFcmp>())
419 InstFcmp(Func, Condition, Dest, Source1, Source2); 428 InstFcmp(Func, Condition, Dest, Source1, Source2);
420 } 429 }
421 FCond getCondition() const { return Condition; } 430 FCond getCondition() const { return Condition; }
422 void dump(const Cfg *Func) const override; 431 void dump(const Cfg *Func) const override;
423 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } 432 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
424 433
425 private: 434 private:
426 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, 435 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
427 Operand *Source2); 436 Operand *Source2);
428 InstFcmp(const InstFcmp &) = delete;
429 InstFcmp &operator=(const InstFcmp &) = delete;
430 ~InstFcmp() override {} 437 ~InstFcmp() override {}
431 const FCond Condition; 438 const FCond Condition;
432 }; 439 };
433 440
434 // Integer comparison instruction. The source operands are captured 441 // Integer comparison instruction. The source operands are captured
435 // in getSrc(0) and getSrc(1). 442 // in getSrc(0) and getSrc(1).
436 class InstIcmp : public InstHighLevel { 443 class InstIcmp : public InstHighLevel {
444 InstIcmp(const InstIcmp &) = delete;
445 InstIcmp &operator=(const InstIcmp &) = delete;
446
437 public: 447 public:
438 enum ICond { 448 enum ICond {
439 #define X(tag, str) tag, 449 #define X(tag, str) tag,
440 ICEINSTICMP_TABLE 450 ICEINSTICMP_TABLE
441 #undef X 451 #undef X
442 _num 452 _num
443 }; 453 };
444 454
445 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, 455 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
446 Operand *Source1, Operand *Source2) { 456 Operand *Source1, Operand *Source2) {
447 return new (Func->allocateInst<InstIcmp>()) 457 return new (Func->allocateInst<InstIcmp>())
448 InstIcmp(Func, Condition, Dest, Source1, Source2); 458 InstIcmp(Func, Condition, Dest, Source1, Source2);
449 } 459 }
450 ICond getCondition() const { return Condition; } 460 ICond getCondition() const { return Condition; }
451 void dump(const Cfg *Func) const override; 461 void dump(const Cfg *Func) const override;
452 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } 462 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
453 463
454 private: 464 private:
455 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, 465 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
456 Operand *Source2); 466 Operand *Source2);
457 InstIcmp(const InstIcmp &) = delete;
458 InstIcmp &operator=(const InstIcmp &) = delete;
459 ~InstIcmp() override {} 467 ~InstIcmp() override {}
460 const ICond Condition; 468 const ICond Condition;
461 }; 469 };
462 470
463 // InsertElement instruction. 471 // InsertElement instruction.
464 class InstInsertElement : public InstHighLevel { 472 class InstInsertElement : public InstHighLevel {
473 InstInsertElement(const InstInsertElement &) = delete;
474 InstInsertElement &operator=(const InstInsertElement &) = delete;
475
465 public: 476 public:
466 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 477 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
467 Operand *Source2, Operand *Source3) { 478 Operand *Source2, Operand *Source3) {
468 return new (Func->allocateInst<InstInsertElement>()) 479 return new (Func->allocateInst<InstInsertElement>())
469 InstInsertElement(Func, Dest, Source1, Source2, Source3); 480 InstInsertElement(Func, Dest, Source1, Source2, Source3);
470 } 481 }
471 482
472 void dump(const Cfg *Func) const override; 483 void dump(const Cfg *Func) const override;
473 static bool classof(const Inst *Inst) { 484 static bool classof(const Inst *Inst) {
474 return Inst->getKind() == InsertElement; 485 return Inst->getKind() == InsertElement;
475 } 486 }
476 487
477 private: 488 private:
478 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, 489 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
479 Operand *Source2, Operand *Source3); 490 Operand *Source2, Operand *Source3);
480 InstInsertElement(const InstInsertElement &) = delete;
481 InstInsertElement &operator=(const InstInsertElement &) = delete;
482 ~InstInsertElement() override {} 491 ~InstInsertElement() override {}
483 }; 492 };
484 493
485 // Call to an intrinsic function. The call target is captured as getSrc(0), 494 // Call to an intrinsic function. The call target is captured as getSrc(0),
486 // and arg I is captured as getSrc(I+1). 495 // and arg I is captured as getSrc(I+1).
487 class InstIntrinsicCall : public InstCall { 496 class InstIntrinsicCall : public InstCall {
497 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
498 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
499
488 public: 500 public:
489 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, 501 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
490 Operand *CallTarget, 502 Operand *CallTarget,
491 const Intrinsics::IntrinsicInfo &Info) { 503 const Intrinsics::IntrinsicInfo &Info) {
492 return new (Func->allocateInst<InstIntrinsicCall>()) 504 return new (Func->allocateInst<InstIntrinsicCall>())
493 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); 505 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
494 } 506 }
495 static bool classof(const Inst *Inst) { 507 static bool classof(const Inst *Inst) {
496 return Inst->getKind() == IntrinsicCall; 508 return Inst->getKind() == IntrinsicCall;
497 } 509 }
498 510
499 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } 511 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
500 512
501 private: 513 private:
502 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, 514 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
503 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) 515 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
504 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, 516 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
505 Inst::IntrinsicCall), 517 Inst::IntrinsicCall),
506 Info(Info) {} 518 Info(Info) {}
507 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
508 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
509 ~InstIntrinsicCall() override {} 519 ~InstIntrinsicCall() override {}
510 const Intrinsics::IntrinsicInfo Info; 520 const Intrinsics::IntrinsicInfo Info;
511 }; 521 };
512 522
513 // Load instruction. The source address is captured in getSrc(0). 523 // Load instruction. The source address is captured in getSrc(0).
514 class InstLoad : public InstHighLevel { 524 class InstLoad : public InstHighLevel {
525 InstLoad(const InstLoad &) = delete;
526 InstLoad &operator=(const InstLoad &) = delete;
527
515 public: 528 public:
516 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, 529 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
517 uint32_t Align = 1) { 530 uint32_t Align = 1) {
518 // TODO(kschimpf) Stop ignoring alignment specification. 531 // TODO(kschimpf) Stop ignoring alignment specification.
519 (void)Align; 532 (void)Align;
520 return new (Func->allocateInst<InstLoad>()) 533 return new (Func->allocateInst<InstLoad>())
521 InstLoad(Func, Dest, SourceAddr); 534 InstLoad(Func, Dest, SourceAddr);
522 } 535 }
523 Operand *getSourceAddress() const { return getSrc(0); } 536 Operand *getSourceAddress() const { return getSrc(0); }
524 void dump(const Cfg *Func) const override; 537 void dump(const Cfg *Func) const override;
525 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } 538 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
526 539
527 private: 540 private:
528 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); 541 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
529 InstLoad(const InstLoad &) = delete;
530 InstLoad &operator=(const InstLoad &) = delete;
531 ~InstLoad() override {} 542 ~InstLoad() override {}
532 }; 543 };
533 544
534 // Phi instruction. For incoming edge I, the node is Labels[I] and 545 // Phi instruction. For incoming edge I, the node is Labels[I] and
535 // the Phi source operand is getSrc(I). 546 // the Phi source operand is getSrc(I).
536 class InstPhi : public InstHighLevel { 547 class InstPhi : public InstHighLevel {
548 InstPhi(const InstPhi &) = delete;
549 InstPhi &operator=(const InstPhi &) = delete;
550
537 public: 551 public:
538 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { 552 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
539 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); 553 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
540 } 554 }
541 void addArgument(Operand *Source, CfgNode *Label); 555 void addArgument(Operand *Source, CfgNode *Label);
542 Operand *getOperandForTarget(CfgNode *Target) const; 556 Operand *getOperandForTarget(CfgNode *Target) const;
543 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target, 557 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
544 Liveness *Liveness); 558 Liveness *Liveness);
545 Inst *lower(Cfg *Func); 559 Inst *lower(Cfg *Func);
546 void dump(const Cfg *Func) const override; 560 void dump(const Cfg *Func) const override;
547 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } 561 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
548 562
549 private: 563 private:
550 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); 564 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
551 InstPhi(const InstPhi &) = delete;
552 InstPhi &operator=(const InstPhi &) = delete;
553 void destroy(Cfg *Func) override { 565 void destroy(Cfg *Func) override {
554 Func->deallocateArrayOf<CfgNode *>(Labels); 566 Func->deallocateArrayOf<CfgNode *>(Labels);
555 Inst::destroy(Func); 567 Inst::destroy(Func);
556 } 568 }
557 ~InstPhi() override {} 569 ~InstPhi() override {}
558 570
559 // Labels[] duplicates the InEdges[] information in the enclosing 571 // Labels[] duplicates the InEdges[] information in the enclosing
560 // CfgNode, but the Phi instruction is created before InEdges[] 572 // CfgNode, but the Phi instruction is created before InEdges[]
561 // is available, so it's more complicated to share the list. 573 // is available, so it's more complicated to share the list.
562 CfgNode **Labels; 574 CfgNode **Labels;
563 }; 575 };
564 576
565 // Ret instruction. The return value is captured in getSrc(0), but if 577 // Ret instruction. The return value is captured in getSrc(0), but if
566 // there is no return value (void-type function), then 578 // there is no return value (void-type function), then
567 // getSrcSize()==0 and hasRetValue()==false. 579 // getSrcSize()==0 and hasRetValue()==false.
568 class InstRet : public InstHighLevel { 580 class InstRet : public InstHighLevel {
581 InstRet(const InstRet &) = delete;
582 InstRet &operator=(const InstRet &) = delete;
583
569 public: 584 public:
570 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) { 585 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
571 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue); 586 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
572 } 587 }
573 bool hasRetValue() const { return getSrcSize(); } 588 bool hasRetValue() const { return getSrcSize(); }
574 Operand *getRetValue() const { 589 Operand *getRetValue() const {
575 assert(hasRetValue()); 590 assert(hasRetValue());
576 return getSrc(0); 591 return getSrc(0);
577 } 592 }
578 NodeList getTerminatorEdges() const override { return NodeList(); } 593 NodeList getTerminatorEdges() const override { return NodeList(); }
579 void dump(const Cfg *Func) const override; 594 void dump(const Cfg *Func) const override;
580 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } 595 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
581 596
582 private: 597 private:
583 InstRet(Cfg *Func, Operand *RetValue); 598 InstRet(Cfg *Func, Operand *RetValue);
584 InstRet(const InstRet &) = delete;
585 InstRet &operator=(const InstRet &) = delete;
586 ~InstRet() override {} 599 ~InstRet() override {}
587 }; 600 };
588 601
589 // Select instruction. The condition, true, and false operands are captured. 602 // Select instruction. The condition, true, and false operands are captured.
590 class InstSelect : public InstHighLevel { 603 class InstSelect : public InstHighLevel {
604 InstSelect(const InstSelect &) = delete;
605 InstSelect &operator=(const InstSelect &) = delete;
606
591 public: 607 public:
592 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, 608 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
593 Operand *SourceTrue, Operand *SourceFalse) { 609 Operand *SourceTrue, Operand *SourceFalse) {
594 return new (Func->allocateInst<InstSelect>()) 610 return new (Func->allocateInst<InstSelect>())
595 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); 611 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
596 } 612 }
597 Operand *getCondition() const { return getSrc(0); } 613 Operand *getCondition() const { return getSrc(0); }
598 Operand *getTrueOperand() const { return getSrc(1); } 614 Operand *getTrueOperand() const { return getSrc(1); }
599 Operand *getFalseOperand() const { return getSrc(2); } 615 Operand *getFalseOperand() const { return getSrc(2); }
600 void dump(const Cfg *Func) const override; 616 void dump(const Cfg *Func) const override;
601 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } 617 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
602 618
603 private: 619 private:
604 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, 620 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
605 Operand *Source2); 621 Operand *Source2);
606 InstSelect(const InstSelect &) = delete;
607 InstSelect &operator=(const InstSelect &) = delete;
608 ~InstSelect() override {} 622 ~InstSelect() override {}
609 }; 623 };
610 624
611 // Store instruction. The address operand is captured, along with the 625 // Store instruction. The address operand is captured, along with the
612 // data operand to be stored into the address. 626 // data operand to be stored into the address.
613 class InstStore : public InstHighLevel { 627 class InstStore : public InstHighLevel {
628 InstStore(const InstStore &) = delete;
629 InstStore &operator=(const InstStore &) = delete;
630
614 public: 631 public:
615 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, 632 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
616 uint32_t align = 1) { 633 uint32_t align = 1) {
617 // TODO(kschimpf) Stop ignoring alignment specification. 634 // TODO(kschimpf) Stop ignoring alignment specification.
618 (void)align; 635 (void)align;
619 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr); 636 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
620 } 637 }
621 Operand *getAddr() const { return getSrc(1); } 638 Operand *getAddr() const { return getSrc(1); }
622 Operand *getData() const { return getSrc(0); } 639 Operand *getData() const { return getSrc(0); }
623 void dump(const Cfg *Func) const override; 640 void dump(const Cfg *Func) const override;
624 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } 641 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
625 642
626 private: 643 private:
627 InstStore(Cfg *Func, Operand *Data, Operand *Addr); 644 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
628 InstStore(const InstStore &) = delete;
629 InstStore &operator=(const InstStore &) = delete;
630 ~InstStore() override {} 645 ~InstStore() override {}
631 }; 646 };
632 647
633 // Switch instruction. The single source operand is captured as 648 // Switch instruction. The single source operand is captured as
634 // getSrc(0). 649 // getSrc(0).
635 class InstSwitch : public InstHighLevel { 650 class InstSwitch : public InstHighLevel {
651 InstSwitch(const InstSwitch &) = delete;
652 InstSwitch &operator=(const InstSwitch &) = delete;
653
636 public: 654 public:
637 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, 655 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
638 CfgNode *LabelDefault) { 656 CfgNode *LabelDefault) {
639 return new (Func->allocateInst<InstSwitch>()) 657 return new (Func->allocateInst<InstSwitch>())
640 InstSwitch(Func, NumCases, Source, LabelDefault); 658 InstSwitch(Func, NumCases, Source, LabelDefault);
641 } 659 }
642 Operand *getComparison() const { return getSrc(0); } 660 Operand *getComparison() const { return getSrc(0); }
643 CfgNode *getLabelDefault() const { return LabelDefault; } 661 CfgNode *getLabelDefault() const { return LabelDefault; }
644 SizeT getNumCases() const { return NumCases; } 662 SizeT getNumCases() const { return NumCases; }
645 uint64_t getValue(SizeT I) const { 663 uint64_t getValue(SizeT I) const {
646 assert(I < NumCases); 664 assert(I < NumCases);
647 return Values[I]; 665 return Values[I];
648 } 666 }
649 CfgNode *getLabel(SizeT I) const { 667 CfgNode *getLabel(SizeT I) const {
650 assert(I < NumCases); 668 assert(I < NumCases);
651 return Labels[I]; 669 return Labels[I];
652 } 670 }
653 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label); 671 void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label);
654 NodeList getTerminatorEdges() const override; 672 NodeList getTerminatorEdges() const override;
655 void dump(const Cfg *Func) const override; 673 void dump(const Cfg *Func) const override;
656 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } 674 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
657 675
658 private: 676 private:
659 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); 677 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
660 InstSwitch(const InstSwitch &) = delete;
661 InstSwitch &operator=(const InstSwitch &) = delete;
662 void destroy(Cfg *Func) override { 678 void destroy(Cfg *Func) override {
663 Func->deallocateArrayOf<uint64_t>(Values); 679 Func->deallocateArrayOf<uint64_t>(Values);
664 Func->deallocateArrayOf<CfgNode *>(Labels); 680 Func->deallocateArrayOf<CfgNode *>(Labels);
665 Inst::destroy(Func); 681 Inst::destroy(Func);
666 } 682 }
667 ~InstSwitch() override {} 683 ~InstSwitch() override {}
668 684
669 CfgNode *LabelDefault; 685 CfgNode *LabelDefault;
670 SizeT NumCases; // not including the default case 686 SizeT NumCases; // not including the default case
671 uint64_t *Values; // size is NumCases 687 uint64_t *Values; // size is NumCases
672 CfgNode **Labels; // size is NumCases 688 CfgNode **Labels; // size is NumCases
673 }; 689 };
674 690
675 // Unreachable instruction. This is a terminator instruction with no 691 // Unreachable instruction. This is a terminator instruction with no
676 // operands. 692 // operands.
677 class InstUnreachable : public InstHighLevel { 693 class InstUnreachable : public InstHighLevel {
694 InstUnreachable(const InstUnreachable &) = delete;
695 InstUnreachable &operator=(const InstUnreachable &) = delete;
696
678 public: 697 public:
679 static InstUnreachable *create(Cfg *Func) { 698 static InstUnreachable *create(Cfg *Func) {
680 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func); 699 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
681 } 700 }
682 NodeList getTerminatorEdges() const override { return NodeList(); } 701 NodeList getTerminatorEdges() const override { return NodeList(); }
683 void dump(const Cfg *Func) const override; 702 void dump(const Cfg *Func) const override;
684 static bool classof(const Inst *Inst) { 703 static bool classof(const Inst *Inst) {
685 return Inst->getKind() == Unreachable; 704 return Inst->getKind() == Unreachable;
686 } 705 }
687 706
688 private: 707 private:
689 InstUnreachable(Cfg *Func); 708 InstUnreachable(Cfg *Func);
690 InstUnreachable(const InstUnreachable &) = delete;
691 InstUnreachable &operator=(const InstUnreachable &) = delete;
692 ~InstUnreachable() override {} 709 ~InstUnreachable() override {}
693 }; 710 };
694 711
695 // FakeDef instruction. This creates a fake definition of a variable, 712 // FakeDef instruction. This creates a fake definition of a variable,
696 // which is how we represent the case when an instruction produces 713 // which is how we represent the case when an instruction produces
697 // multiple results. This doesn't happen with high-level ICE 714 // multiple results. This doesn't happen with high-level ICE
698 // instructions, but might with lowered instructions. For example, 715 // instructions, but might with lowered instructions. For example,
699 // this would be a way to represent condition flags being modified by 716 // this would be a way to represent condition flags being modified by
700 // an instruction. 717 // an instruction.
701 // 718 //
702 // It's generally useful to set the optional source operand to be the 719 // It's generally useful to set the optional source operand to be the
703 // dest variable of the instruction that actually produces the FakeDef 720 // dest variable of the instruction that actually produces the FakeDef
704 // dest. Otherwise, the original instruction could be dead-code 721 // dest. Otherwise, the original instruction could be dead-code
705 // eliminated if its dest operand is unused, and therefore the FakeDef 722 // eliminated if its dest operand is unused, and therefore the FakeDef
706 // dest wouldn't be properly initialized. 723 // dest wouldn't be properly initialized.
707 class InstFakeDef : public InstHighLevel { 724 class InstFakeDef : public InstHighLevel {
725 InstFakeDef(const InstFakeDef &) = delete;
726 InstFakeDef &operator=(const InstFakeDef &) = delete;
727
708 public: 728 public:
709 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) { 729 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
710 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src); 730 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
711 } 731 }
712 void emit(const Cfg *Func) const override; 732 void emit(const Cfg *Func) const override;
713 void emitIAS(const Cfg *Func) const override { emit(Func); } 733 void emitIAS(const Cfg *Func) const override { emit(Func); }
714 void dump(const Cfg *Func) const override; 734 void dump(const Cfg *Func) const override;
715 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } 735 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
716 736
717 private: 737 private:
718 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); 738 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
719 InstFakeDef(const InstFakeDef &) = delete;
720 InstFakeDef &operator=(const InstFakeDef &) = delete;
721 ~InstFakeDef() override {} 739 ~InstFakeDef() override {}
722 }; 740 };
723 741
724 // FakeUse instruction. This creates a fake use of a variable, to 742 // FakeUse instruction. This creates a fake use of a variable, to
725 // keep the instruction that produces that variable from being 743 // keep the instruction that produces that variable from being
726 // dead-code eliminated. This is useful in a variety of lowering 744 // dead-code eliminated. This is useful in a variety of lowering
727 // situations. The FakeUse instruction has no dest, so it can itself 745 // situations. The FakeUse instruction has no dest, so it can itself
728 // never be dead-code eliminated. 746 // never be dead-code eliminated.
729 class InstFakeUse : public InstHighLevel { 747 class InstFakeUse : public InstHighLevel {
748 InstFakeUse(const InstFakeUse &) = delete;
749 InstFakeUse &operator=(const InstFakeUse &) = delete;
750
730 public: 751 public:
731 static InstFakeUse *create(Cfg *Func, Variable *Src) { 752 static InstFakeUse *create(Cfg *Func, Variable *Src) {
732 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src); 753 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
733 } 754 }
734 void emit(const Cfg *Func) const override; 755 void emit(const Cfg *Func) const override;
735 void emitIAS(const Cfg *Func) const override { emit(Func); } 756 void emitIAS(const Cfg *Func) const override { emit(Func); }
736 void dump(const Cfg *Func) const override; 757 void dump(const Cfg *Func) const override;
737 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } 758 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
738 759
739 private: 760 private:
740 InstFakeUse(Cfg *Func, Variable *Src); 761 InstFakeUse(Cfg *Func, Variable *Src);
741 InstFakeUse(const InstFakeUse &) = delete;
742 InstFakeUse &operator=(const InstFakeUse &) = delete;
743 ~InstFakeUse() override {} 762 ~InstFakeUse() override {}
744 }; 763 };
745 764
746 // FakeKill instruction. This "kills" a set of variables by adding a 765 // FakeKill instruction. This "kills" a set of variables by adding a
747 // trivial live range at this instruction to each variable. The 766 // trivial live range at this instruction to each variable. The
748 // primary use is to indicate that scratch registers are killed after 767 // primary use is to indicate that scratch registers are killed after
749 // a call, so that the register allocator won't assign a scratch 768 // a call, so that the register allocator won't assign a scratch
750 // register to a variable whose live range spans a call. 769 // register to a variable whose live range spans a call.
751 // 770 //
752 // The FakeKill instruction also holds a pointer to the instruction 771 // The FakeKill instruction also holds a pointer to the instruction
753 // that kills the set of variables, so that if that linked instruction 772 // that kills the set of variables, so that if that linked instruction
754 // gets dead-code eliminated, the FakeKill instruction will as well. 773 // gets dead-code eliminated, the FakeKill instruction will as well.
755 class InstFakeKill : public InstHighLevel { 774 class InstFakeKill : public InstHighLevel {
775 InstFakeKill(const InstFakeKill &) = delete;
776 InstFakeKill &operator=(const InstFakeKill &) = delete;
777
756 public: 778 public:
757 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs, 779 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
758 const Inst *Linked) { 780 const Inst *Linked) {
759 return new (Func->allocateInst<InstFakeKill>()) 781 return new (Func->allocateInst<InstFakeKill>())
760 InstFakeKill(Func, KilledRegs, Linked); 782 InstFakeKill(Func, KilledRegs, Linked);
761 } 783 }
762 const Inst *getLinked() const { return Linked; } 784 const Inst *getLinked() const { return Linked; }
763 void emit(const Cfg *Func) const override; 785 void emit(const Cfg *Func) const override;
764 void emitIAS(const Cfg *Func) const override { emit(Func); } 786 void emitIAS(const Cfg *Func) const override { emit(Func); }
765 void dump(const Cfg *Func) const override; 787 void dump(const Cfg *Func) const override;
766 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } 788 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
767 789
768 private: 790 private:
769 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked); 791 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
770 InstFakeKill(const InstFakeKill &) = delete;
771 InstFakeKill &operator=(const InstFakeKill &) = delete;
772 ~InstFakeKill() override {} 792 ~InstFakeKill() override {}
773 793
774 // This instruction is ignored if Linked->isDeleted() is true. 794 // This instruction is ignored if Linked->isDeleted() is true.
775 const Inst *Linked; 795 const Inst *Linked;
776 }; 796 };
777 797
778 // The Target instruction is the base class for all target-specific 798 // The Target instruction is the base class for all target-specific
779 // instructions. 799 // instructions.
780 class InstTarget : public Inst { 800 class InstTarget : public Inst {
781 InstTarget(const InstTarget &) = delete; 801 InstTarget(const InstTarget &) = delete;
782 InstTarget &operator=(const InstTarget &) = delete; 802 InstTarget &operator=(const InstTarget &) = delete;
783 803
784 public: 804 public:
785 uint32_t getEmitInstCount() const override { return 1; } 805 uint32_t getEmitInstCount() const override { return 1; }
786 void dump(const Cfg *Func) const override; 806 void dump(const Cfg *Func) const override;
787 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } 807 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
788 808
789 protected: 809 protected:
790 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 810 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
791 : Inst(Func, Kind, MaxSrcs, Dest) { 811 : Inst(Func, Kind, MaxSrcs, Dest) {
792 assert(Kind >= Target); 812 assert(Kind >= Target);
793 } 813 }
794 void emitIAS(const Cfg *Func) const override { emit(Func); } 814 void emitIAS(const Cfg *Func) const override { emit(Func); }
795 ~InstTarget() override {} 815 ~InstTarget() override {}
796 }; 816 };
797 817
798 } // end of namespace Ice 818 } // end of namespace Ice
799 819
800 #endif // SUBZERO_SRC_ICEINST_H 820 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceInstX8632.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698