LLVM  7.0.0svn
MachineIRBuilder.cpp
Go to the documentation of this file.
1 //===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- 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 /// This file implements the MachineIRBuidler class.
11 //===----------------------------------------------------------------------===//
13 
21 #include "llvm/IR/DebugInfo.h"
22 
23 using namespace llvm;
24 
26  this->MF = &MF;
27  this->MBB = nullptr;
28  this->MRI = &MF.getRegInfo();
29  this->TII = MF.getSubtarget().getInstrInfo();
30  this->DL = DebugLoc();
31  this->II = MachineBasicBlock::iterator();
32  this->InsertedInstr = nullptr;
33 }
34 
36  this->MBB = &MBB;
37  this->II = MBB.end();
38  assert(&getMF() == MBB.getParent() &&
39  "Basic block is in a different function");
40 }
41 
43  assert(MI.getParent() && "Instruction is not part of a basic block");
44  setMBB(*MI.getParent());
45  this->II = MI.getIterator();
46 }
47 
50  assert(MBB.getParent() == &getMF() &&
51  "Basic block is in a different function");
52  this->MBB = &MBB;
53  this->II = II;
54 }
55 
57  std::function<void(MachineInstr *)> Inserted) {
58  InsertedInstr = std::move(Inserted);
59 }
60 
62  InsertedInstr = nullptr;
63 }
64 
65 //------------------------------------------------------------------------------
66 // Build instruction variants.
67 //------------------------------------------------------------------------------
68 
70  return insertInstr(buildInstrNoInsert(Opcode));
71 }
72 
74  MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
75  return MIB;
76 }
77 
78 
80  getMBB().insert(getInsertPt(), MIB);
81  if (InsertedInstr)
82  InsertedInstr(MIB);
83  return MIB;
84 }
85 
88  const MDNode *Expr) {
89  assert(isa<DILocalVariable>(Variable) && "not a variable");
90  assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
91  assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
92  "Expected inlined-at fields to agree");
93  return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
94  /*IsIndirect*/ false, Reg, Variable, Expr));
95 }
96 
99  const MDNode *Expr) {
100  assert(isa<DILocalVariable>(Variable) && "not a variable");
101  assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
102  assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
103  "Expected inlined-at fields to agree");
104  return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
105  /*IsIndirect*/ true, Reg, Variable, Expr));
106 }
107 
109  const MDNode *Variable,
110  const MDNode *Expr) {
111  assert(isa<DILocalVariable>(Variable) && "not a variable");
112  assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
113  assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
114  "Expected inlined-at fields to agree");
115  return buildInstr(TargetOpcode::DBG_VALUE)
116  .addFrameIndex(FI)
117  .addImm(0)
118  .addMetadata(Variable)
119  .addMetadata(Expr);
120 }
121 
123  const MDNode *Variable,
124  const MDNode *Expr) {
125  assert(isa<DILocalVariable>(Variable) && "not a variable");
126  assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
127  assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
128  "Expected inlined-at fields to agree");
129  auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
130  if (auto *CI = dyn_cast<ConstantInt>(&C)) {
131  if (CI->getBitWidth() > 64)
132  MIB.addCImm(CI);
133  else
134  MIB.addImm(CI->getZExtValue());
135  } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
136  MIB.addFPImm(CFP);
137  } else {
138  // Insert %noreg if we didn't find a usable constant and had to drop it.
139  MIB.addReg(0U);
140  }
141 
142  return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
143 }
144 
146  assert(MRI->getType(Res).isPointer() && "invalid operand type");
147  return buildInstr(TargetOpcode::G_FRAME_INDEX)
148  .addDef(Res)
149  .addFrameIndex(Idx);
150 }
151 
153  const GlobalValue *GV) {
154  assert(MRI->getType(Res).isPointer() && "invalid operand type");
155  assert(MRI->getType(Res).getAddressSpace() ==
156  GV->getType()->getAddressSpace() &&
157  "address space mismatch");
158 
159  return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
160  .addDef(Res)
161  .addGlobalAddress(GV);
162 }
163 
164 MachineInstrBuilder MachineIRBuilder::buildBinaryOp(unsigned Opcode, unsigned Res, unsigned Op0,
165  unsigned Op1) {
166  assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
167  "invalid operand type");
168  assert(MRI->getType(Res) == MRI->getType(Op0) &&
169  MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
170 
171  return buildInstr(Opcode)
172  .addDef(Res)
173  .addUse(Op0)
174  .addUse(Op1);
175 }
176 
178  unsigned Op1) {
179  return buildBinaryOp(TargetOpcode::G_ADD, Res, Op0, Op1);
180 }
181 
183  unsigned Op1) {
184  assert(MRI->getType(Res).isPointer() &&
185  MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
186  assert(MRI->getType(Op1).isScalar() && "invalid offset type");
187 
188  return buildInstr(TargetOpcode::G_GEP)
189  .addDef(Res)
190  .addUse(Op0)
191  .addUse(Op1);
192 }
193 
195 MachineIRBuilder::materializeGEP(unsigned &Res, unsigned Op0,
196  const LLT &ValueTy, uint64_t Value) {
197  assert(Res == 0 && "Res is a result argument");
198  assert(ValueTy.isScalar() && "invalid offset type");
199 
200  if (Value == 0) {
201  Res = Op0;
202  return None;
203  }
204 
205  Res = MRI->createGenericVirtualRegister(MRI->getType(Op0));
206  unsigned TmpReg = MRI->createGenericVirtualRegister(ValueTy);
207 
208  buildConstant(TmpReg, Value);
209  return buildGEP(Res, Op0, TmpReg);
210 }
211 
213  uint32_t NumBits) {
214  assert(MRI->getType(Res).isPointer() &&
215  MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
216 
217  return buildInstr(TargetOpcode::G_PTR_MASK)
218  .addDef(Res)
219  .addUse(Op0)
220  .addImm(NumBits);
221 }
222 
224  unsigned Op1) {
225  return buildBinaryOp(TargetOpcode::G_SUB, Res, Op0, Op1);
226 }
227 
229  unsigned Op1) {
230  return buildBinaryOp(TargetOpcode::G_MUL, Res, Op0, Op1);
231 }
232 
234  unsigned Op1) {
235  return buildBinaryOp(TargetOpcode::G_AND, Res, Op0, Op1);
236 }
237 
239  unsigned Op1) {
240  return buildBinaryOp(TargetOpcode::G_OR, Res, Op0, Op1);
241 }
242 
244  return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
245 }
246 
248  assert(MRI->getType(Tgt).isPointer() && "invalid branch destination");
249  return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
250 }
251 
253  assert(MRI->getType(Res) == LLT() || MRI->getType(Op) == LLT() ||
254  MRI->getType(Res) == MRI->getType(Op));
255  return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
256 }
257 
259  const ConstantInt &Val) {
260  LLT Ty = MRI->getType(Res);
261 
262  assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
263 
264  const ConstantInt *NewVal = &Val;
265  if (Ty.getSizeInBits() != Val.getBitWidth())
266  NewVal = ConstantInt::get(MF->getFunction().getContext(),
267  Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
268 
269  return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
270 }
271 
273  int64_t Val) {
274  auto IntN = IntegerType::get(MF->getFunction().getContext(),
275  MRI->getType(Res).getSizeInBits());
276  ConstantInt *CI = ConstantInt::get(IntN, Val, true);
277  return buildConstant(Res, *CI);
278 }
279 
281  const ConstantFP &Val) {
282  assert(MRI->getType(Res).isScalar() && "invalid operand type");
283 
284  return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
285 }
286 
288  MachineBasicBlock &Dest) {
289  assert(MRI->getType(Tst).isScalar() && "invalid operand type");
290 
291  return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
292 }
293 
295  MachineMemOperand &MMO) {
296  assert(MRI->getType(Res).isValid() && "invalid operand type");
297  assert(MRI->getType(Addr).isPointer() && "invalid operand type");
298 
299  return buildInstr(TargetOpcode::G_LOAD)
300  .addDef(Res)
301  .addUse(Addr)
302  .addMemOperand(&MMO);
303 }
304 
306  MachineMemOperand &MMO) {
307  assert(MRI->getType(Val).isValid() && "invalid operand type");
308  assert(MRI->getType(Addr).isPointer() && "invalid operand type");
309 
310  return buildInstr(TargetOpcode::G_STORE)
311  .addUse(Val)
312  .addUse(Addr)
313  .addMemOperand(&MMO);
314 }
315 
317  unsigned CarryOut,
318  unsigned Op0, unsigned Op1,
319  unsigned CarryIn) {
320  assert(MRI->getType(Res).isScalar() && "invalid operand type");
321  assert(MRI->getType(Res) == MRI->getType(Op0) &&
322  MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
323  assert(MRI->getType(CarryOut).isScalar() && "invalid operand type");
324  assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch");
325 
326  return buildInstr(TargetOpcode::G_UADDE)
327  .addDef(Res)
328  .addDef(CarryOut)
329  .addUse(Op0)
330  .addUse(Op1)
331  .addUse(CarryIn);
332 }
333 
335  validateTruncExt(Res, Op, true);
336  return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
337 }
338 
340  validateTruncExt(Res, Op, true);
341  return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
342 }
343 
345  validateTruncExt(Res, Op, true);
346  return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
347 }
348 
350 MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc, unsigned Res, unsigned Op) {
351  assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
352  TargetOpcode::G_SEXT == ExtOpc) &&
353  "Expecting Extending Opc");
354  assert(MRI->getType(Res).isScalar() || MRI->getType(Res).isVector());
355  assert(MRI->getType(Res).isScalar() == MRI->getType(Op).isScalar());
356 
357  unsigned Opcode = TargetOpcode::COPY;
358  if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
359  Opcode = ExtOpc;
360  else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
361  Opcode = TargetOpcode::G_TRUNC;
362  else
363  assert(MRI->getType(Res) == MRI->getType(Op));
364 
365  return buildInstr(Opcode).addDef(Res).addUse(Op);
366 }
367 
369  unsigned Op) {
370  return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
371 }
372 
374  unsigned Op) {
375  return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
376 }
377 
379  unsigned Op) {
380  return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
381 }
382 
384  LLT SrcTy = MRI->getType(Src);
385  LLT DstTy = MRI->getType(Dst);
386  if (SrcTy == DstTy)
387  return buildCopy(Dst, Src);
388 
389  unsigned Opcode;
390  if (SrcTy.isPointer() && DstTy.isScalar())
391  Opcode = TargetOpcode::G_PTRTOINT;
392  else if (DstTy.isPointer() && SrcTy.isScalar())
393  Opcode = TargetOpcode::G_INTTOPTR;
394  else {
395  assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
396  Opcode = TargetOpcode::G_BITCAST;
397  }
398 
399  return buildInstr(Opcode).addDef(Dst).addUse(Src);
400 }
401 
403  uint64_t Index) {
404 #ifndef NDEBUG
405  assert(MRI->getType(Src).isValid() && "invalid operand type");
406  assert(MRI->getType(Res).isValid() && "invalid operand type");
407  assert(Index + MRI->getType(Res).getSizeInBits() <=
408  MRI->getType(Src).getSizeInBits() &&
409  "extracting off end of register");
410 #endif
411 
412  if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) {
413  assert(Index == 0 && "insertion past the end of a register");
414  return buildCast(Res, Src);
415  }
416 
417  return buildInstr(TargetOpcode::G_EXTRACT)
418  .addDef(Res)
419  .addUse(Src)
420  .addImm(Index);
421 }
422 
424  ArrayRef<uint64_t> Indices) {
425 #ifndef NDEBUG
426  assert(Ops.size() == Indices.size() && "incompatible args");
427  assert(!Ops.empty() && "invalid trivial sequence");
428  assert(std::is_sorted(Indices.begin(), Indices.end()) &&
429  "sequence offsets must be in ascending order");
430 
431  assert(MRI->getType(Res).isValid() && "invalid operand type");
432  for (auto Op : Ops)
433  assert(MRI->getType(Op).isValid() && "invalid operand type");
434 #endif
435 
436  LLT ResTy = MRI->getType(Res);
437  LLT OpTy = MRI->getType(Ops[0]);
438  unsigned OpSize = OpTy.getSizeInBits();
439  bool MaybeMerge = true;
440  for (unsigned i = 0; i < Ops.size(); ++i) {
441  if (MRI->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
442  MaybeMerge = false;
443  break;
444  }
445  }
446 
447  if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
448  buildMerge(Res, Ops);
449  return;
450  }
451 
452  unsigned ResIn = MRI->createGenericVirtualRegister(ResTy);
453  buildUndef(ResIn);
454 
455  for (unsigned i = 0; i < Ops.size(); ++i) {
456  unsigned ResOut =
457  i + 1 == Ops.size() ? Res : MRI->createGenericVirtualRegister(ResTy);
458  buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
459  ResIn = ResOut;
460  }
461 }
462 
464  return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
465 }
466 
468  ArrayRef<unsigned> Ops) {
469 
470 #ifndef NDEBUG
471  assert(!Ops.empty() && "invalid trivial sequence");
472  LLT Ty = MRI->getType(Ops[0]);
473  for (auto Reg : Ops)
474  assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
475  assert(Ops.size() * MRI->getType(Ops[0]).getSizeInBits() ==
476  MRI->getType(Res).getSizeInBits() &&
477  "input operands do not cover output register");
478 #endif
479 
480  if (Ops.size() == 1)
481  return buildCast(Res, Ops[0]);
482 
483  MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
484  MIB.addDef(Res);
485  for (unsigned i = 0; i < Ops.size(); ++i)
486  MIB.addUse(Ops[i]);
487  return MIB;
488 }
489 
491  unsigned Op) {
492 
493 #ifndef NDEBUG
494  assert(!Res.empty() && "invalid trivial sequence");
495  LLT Ty = MRI->getType(Res[0]);
496  for (auto Reg : Res)
497  assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
498  assert(Res.size() * MRI->getType(Res[0]).getSizeInBits() ==
499  MRI->getType(Op).getSizeInBits() &&
500  "input operands do not cover output register");
501 #endif
502 
503  MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
504  for (unsigned i = 0; i < Res.size(); ++i)
505  MIB.addDef(Res[i]);
506  MIB.addUse(Op);
507  return MIB;
508 }
509 
511  unsigned Op, unsigned Index) {
512  assert(Index + MRI->getType(Op).getSizeInBits() <=
513  MRI->getType(Res).getSizeInBits() &&
514  "insertion past the end of a register");
515 
516  if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
517  return buildCast(Res, Op);
518  }
519 
520  return buildInstr(TargetOpcode::G_INSERT)
521  .addDef(Res)
522  .addUse(Src)
523  .addUse(Op)
524  .addImm(Index);
525 }
526 
528  unsigned Res,
529  bool HasSideEffects) {
530  auto MIB =
531  buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
532  : TargetOpcode::G_INTRINSIC);
533  if (Res)
534  MIB.addDef(Res);
535  MIB.addIntrinsicID(ID);
536  return MIB;
537 }
538 
540  validateTruncExt(Res, Op, false);
541  return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
542 }
543 
545  validateTruncExt(Res, Op, false);
546  return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
547 }
548 
550  unsigned Res, unsigned Op0,
551  unsigned Op1) {
552 #ifndef NDEBUG
553  assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch");
554  assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
555  if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer())
556  assert(MRI->getType(Res).isScalar() && "type mismatch");
557  else
558  assert(MRI->getType(Res).isVector() &&
559  MRI->getType(Res).getNumElements() ==
560  MRI->getType(Op0).getNumElements() &&
561  "type mismatch");
562 #endif
563 
564  return buildInstr(TargetOpcode::G_ICMP)
565  .addDef(Res)
566  .addPredicate(Pred)
567  .addUse(Op0)
568  .addUse(Op1);
569 }
570 
572  unsigned Res, unsigned Op0,
573  unsigned Op1) {
574 #ifndef NDEBUG
575  assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) &&
576  "invalid operand type");
577  assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch");
578  assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
579  if (MRI->getType(Op0).isScalar())
580  assert(MRI->getType(Res).isScalar() && "type mismatch");
581  else
582  assert(MRI->getType(Res).isVector() &&
583  MRI->getType(Res).getNumElements() ==
584  MRI->getType(Op0).getNumElements() &&
585  "type mismatch");
586 #endif
587 
588  return buildInstr(TargetOpcode::G_FCMP)
589  .addDef(Res)
590  .addPredicate(Pred)
591  .addUse(Op0)
592  .addUse(Op1);
593 }
594 
596  unsigned Op0, unsigned Op1) {
597 #ifndef NDEBUG
598  LLT ResTy = MRI->getType(Res);
599  assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
600  "invalid operand type");
601  assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) &&
602  "type mismatch");
603  if (ResTy.isScalar() || ResTy.isPointer())
604  assert(MRI->getType(Tst).isScalar() && "type mismatch");
605  else
606  assert((MRI->getType(Tst).isScalar() ||
607  (MRI->getType(Tst).isVector() &&
608  MRI->getType(Tst).getNumElements() ==
609  MRI->getType(Op0).getNumElements())) &&
610  "type mismatch");
611 #endif
612 
613  return buildInstr(TargetOpcode::G_SELECT)
614  .addDef(Res)
615  .addUse(Tst)
616  .addUse(Op0)
617  .addUse(Op1);
618 }
619 
621  unsigned Val,
622  unsigned Elt,
623  unsigned Idx) {
624 #ifndef NDEBUG
625  LLT ResTy = MRI->getType(Res);
626  LLT ValTy = MRI->getType(Val);
627  LLT EltTy = MRI->getType(Elt);
628  LLT IdxTy = MRI->getType(Idx);
629  assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type");
630  assert(IdxTy.isScalar() && "invalid operand type");
631  assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch");
632  assert(ResTy.getElementType() == EltTy && "type mismatch");
633 #endif
634 
635  return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT)
636  .addDef(Res)
637  .addUse(Val)
638  .addUse(Elt)
639  .addUse(Idx);
640 }
641 
643  unsigned Val,
644  unsigned Idx) {
645 #ifndef NDEBUG
646  LLT ResTy = MRI->getType(Res);
647  LLT ValTy = MRI->getType(Val);
648  LLT IdxTy = MRI->getType(Idx);
649  assert(ValTy.isVector() && "invalid operand type");
650  assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type");
651  assert(IdxTy.isScalar() && "invalid operand type");
652  assert(ValTy.getElementType() == ResTy && "type mismatch");
653 #endif
654 
655  return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
656  .addDef(Res)
657  .addUse(Val)
658  .addUse(Idx);
659 }
660 
662 MachineIRBuilder::buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr,
663  unsigned CmpVal, unsigned NewVal,
664  MachineMemOperand &MMO) {
665 #ifndef NDEBUG
666  LLT OldValResTy = MRI->getType(OldValRes);
667  LLT AddrTy = MRI->getType(Addr);
668  LLT CmpValTy = MRI->getType(CmpVal);
669  LLT NewValTy = MRI->getType(NewVal);
670  assert(OldValResTy.isScalar() && "invalid operand type");
671  assert(AddrTy.isPointer() && "invalid operand type");
672  assert(CmpValTy.isValid() && "invalid operand type");
673  assert(NewValTy.isValid() && "invalid operand type");
674  assert(OldValResTy == CmpValTy && "type mismatch");
675  assert(OldValResTy == NewValTy && "type mismatch");
676 #endif
677 
678  return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
679  .addDef(OldValRes)
680  .addUse(Addr)
681  .addUse(CmpVal)
682  .addUse(NewVal)
683  .addMemOperand(&MMO);
684 }
685 
686 void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
687  bool IsExtend) {
688 #ifndef NDEBUG
689  LLT SrcTy = MRI->getType(Src);
690  LLT DstTy = MRI->getType(Dst);
691 
692  if (DstTy.isVector()) {
693  assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
694  assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
695  "different number of elements in a trunc/ext");
696  } else
697  assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
698 
699  if (IsExtend)
700  assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
701  "invalid narrowing extend");
702  else
703  assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
704  "invalid widening trunc");
705 #endif
706 }
bool isFPPredicate() const
Definition: InstrTypes.h:944
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
uint64_t CallInst * C
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MachineInstrBuilder buildIndirectDbgValue(unsigned Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
iterator begin() const
Definition: ArrayRef.h:137
bool isScalar() const
const MachineInstrBuilder & addPredicate(CmpInst::Predicate Pred) const
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildAnyExtOrTrunc(DstTy &&Dst, UseArgTy &&Use)
Res = COPY Op depending on the differing sizes of Res and Op.
A debug info location.
Definition: DebugLoc.h:34
Metadata node.
Definition: Metadata.h:862
MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op)
Build and insert Res = G_ANYEXT Op0.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index)
Build and insert `Res0, ...
unsigned getBitWidth() const
getBitWidth - Return the bitwidth of this constant.
Definition: Constants.h:143
MachineInstrBuilder buildSelect(unsigned Res, unsigned Tst, unsigned Op0, unsigned Op1)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildExtOrTrunc(unsigned ExtOpc, unsigned Res, unsigned Op)
Build and insert Res = ExtOpc, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes of...
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool isVector() const
A description of a memory reference used in the backend.
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
MachineInstrBuilder buildFPTrunc(DstType &&Res, SrcType &&Src)
Build and insert Res = G_FPTRUNC Op.
Reg
All possible values of the reg field in the ModR/M byte.
MachineInstrBuilder buildExtractVectorElement(unsigned Res, unsigned Val, unsigned Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
LLT getElementType() const
Returns the vector&#39;s element type. Only valid for vector types.
MachineInstrBuilder buildInsertVectorElement(unsigned Res, unsigned Val, unsigned Elt, unsigned Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildSExtOrTrunc(DstTy &&Dst, UseArgTy &&Use)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don&#39;t insert <empty> = Opcode <empty>.
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition: APInt.cpp:892
MachineFunction & getMF()
Getter for the function we currently build.
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:138
void recordInsertions(std::function< void(MachineInstr *)> InsertedInstr)
MachineInstrBuilder buildOr(DstTy &&Dst, UseArgsTy &&... UseArgs)
Build and insert Res = G_OR Op0, Op1.
virtual const TargetInstrInfo * getInstrInfo() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineInstrBuilder buildMul(DstTy &&Ty, UseArgsTy &&... UseArgs)
Build and insert Res = G_MUL Op0, Op1.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_SEXT Op.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
MachineInstrBuilder buildBr(MachineBasicBlock &BB)
Build and insert G_BR Dest.
MachineInstrBundleIterator< MachineInstr > iterator
const MachineInstrBuilder & addCImm(const ConstantInt *Val) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
This is an important base class in LLVM.
Definition: Constant.h:42
MachineInstrBuilder buildPtrMask(unsigned Res, unsigned Op0, uint32_t NumBits)
Build and insert Res = G_PTR_MASK Op0, NumBits.
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, unsigned Res, bool HasSideEffects)
Build and insert either a G_INTRINSIC (if HasSideEffects is false) or G_INTRINSIC_W_SIDE_EFFECTS inst...
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildUndef(DstType &&Res)
Build and insert Res = IMPLICIT_DEF.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
bool isValid() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:853
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index)
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildCast(DstType &&Res, ArgType &&Arg)
Build and insert an appropriate cast between two registers of equal size.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:495
self_iterator getIterator()
Definition: ilist_node.h:82
unsigned getAddressSpace() const
void setMF(MachineFunction &)
const MachineInstrBuilder & addFrameIndex(int Idx) const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:194
MachineInstrBuilder buildBrIndirect(unsigned Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0, unsigned Op1, unsigned CarryIn)
Build and insert Res, CarryOut = G_UADDE Op0, Op1, CarryIn.
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:240
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
void buildSequence(unsigned Res, ArrayRef< unsigned > Ops, ArrayRef< uint64_t > Indices)
Build and insert instructions to put Ops together at the specified p Indices to form a larger registe...
MachineInstrBuilder buildCopy(unsigned Res, unsigned Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildZExtOrTrunc(DstTy &&Dst, UseArgTy &&Use)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
iterator end() const
Definition: ArrayRef.h:138
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:598
const Function & getFunction() const
Return the LLVM function that this machine code represents.
This file declares the MachineIRBuilder class.
bool isIntPredicate() const
Definition: InstrTypes.h:945
bool isPointer() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:142
Representation of each machine instruction.
Definition: MachineInstr.h:60
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBuilder buildDirectDbgValue(unsigned Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineInstrBuilder buildAdd(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_ADD Op0, Op1.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
MachineInstrBuilder buildFConstant(DstType &&Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
Optional< MachineInstrBuilder > materializeGEP(unsigned &Res, unsigned Op0, const LLT &ValueTy, uint64_t Value)
Materialize and insert Res = G_GEP Op0, (G_CONSTANT Value)
MachineInstrBuilder buildUnmerge(ArrayRef< unsigned > Res, unsigned Op)
Build and insert Res0, ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVM Value Representation.
Definition: Value.h:73
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
print Print MemDeps of function
MachineInstrBuilder buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr, unsigned CmpVal, unsigned NewVal, MachineMemOperand &MMO)
Build and insert OldValRes = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal, MMO.
IRTranslator LLVM IR MI
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
MachineInstrBuilder buildAnd(DstTy &&Dst, UseArgsTy &&... UseArgs)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildGlobalValue(unsigned Res, const GlobalValue *GV)
Build and insert Res = G_GLOBAL_VALUE GV.
MachineInstrBuilder buildMerge(unsigned Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
MachineInstrBuilder buildZExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_ZEXT Op.
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:273
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
MachineInstrBuilder buildSub(DstTy &&Ty, UseArgsTy &&... UseArgs)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &BB)
Build and insert G_BRCOND Tst, Dest.