LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - MachineIRBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 192 207 92.8 %
Date: 2018-06-17 00:07:59 Functions: 54 56 96.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : //===----------------------------------------------------------------------===//
      12             : #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
      13             : 
      14             : #include "llvm/CodeGen/MachineFunction.h"
      15             : #include "llvm/CodeGen/MachineInstr.h"
      16             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      17             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      18             : #include "llvm/CodeGen/TargetInstrInfo.h"
      19             : #include "llvm/CodeGen/TargetOpcodes.h"
      20             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      21             : #include "llvm/IR/DebugInfo.h"
      22             : 
      23             : using namespace llvm;
      24             : 
      25        4533 : void MachineIRBuilderBase::setMF(MachineFunction &MF) {
      26        4533 :   State.MF = &MF;
      27        4533 :   State.MBB = nullptr;
      28        4533 :   State.MRI = &MF.getRegInfo();
      29        4533 :   State.TII = MF.getSubtarget().getInstrInfo();
      30        9066 :   State.DL = DebugLoc();
      31        4533 :   State.II = MachineBasicBlock::iterator();
      32             :   State.InsertedInstr = nullptr;
      33        4533 : }
      34             : 
      35        5439 : void MachineIRBuilderBase::setMBB(MachineBasicBlock &MBB) {
      36        5439 :   State.MBB = &MBB;
      37        5439 :   State.II = MBB.end();
      38             :   assert(&getMF() == MBB.getParent() &&
      39             :          "Basic block is in a different function");
      40        5439 : }
      41             : 
      42        1215 : void MachineIRBuilderBase::setInstr(MachineInstr &MI) {
      43             :   assert(MI.getParent() && "Instruction is not part of a basic block");
      44        1215 :   setMBB(*MI.getParent());
      45        1215 :   State.II = MI.getIterator();
      46        1215 : }
      47             : 
      48         271 : void MachineIRBuilderBase::setInsertPt(MachineBasicBlock &MBB,
      49             :                                        MachineBasicBlock::iterator II) {
      50             :   assert(MBB.getParent() == &getMF() &&
      51             :          "Basic block is in a different function");
      52         271 :   State.MBB = &MBB;
      53         271 :   State.II = II;
      54         271 : }
      55             : 
      56       13511 : void MachineIRBuilderBase::recordInsertion(MachineInstr *InsertedInstr) const {
      57       13511 :   if (State.InsertedInstr)
      58             :     State.InsertedInstr(InsertedInstr);
      59       13511 : }
      60             : 
      61        1312 : void MachineIRBuilderBase::recordInsertions(
      62             :     std::function<void(MachineInstr *)> Inserted) {
      63        1312 :   State.InsertedInstr = std::move(Inserted);
      64        1312 : }
      65             : 
      66          30 : void MachineIRBuilderBase::stopRecordingInsertions() {
      67             :   State.InsertedInstr = nullptr;
      68          30 : }
      69             : 
      70             : //------------------------------------------------------------------------------
      71             : // Build instruction variants.
      72             : //------------------------------------------------------------------------------
      73             : 
      74       11928 : MachineInstrBuilder MachineIRBuilderBase::buildInstr(unsigned Opcode) {
      75       11928 :   return insertInstr(buildInstrNoInsert(Opcode));
      76             : }
      77             : 
      78       13422 : MachineInstrBuilder MachineIRBuilderBase::buildInstrNoInsert(unsigned Opcode) {
      79       26844 :   MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode));
      80       13422 :   return MIB;
      81             : }
      82             : 
      83       13249 : MachineInstrBuilder MachineIRBuilderBase::insertInstr(MachineInstrBuilder MIB) {
      84       13249 :   getMBB().insert(getInsertPt(), MIB);
      85       13249 :   recordInsertion(MIB);
      86       13249 :   return MIB;
      87             : }
      88             : 
      89             : MachineInstrBuilder
      90          10 : MachineIRBuilderBase::buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
      91             :                                           const MDNode *Expr) {
      92             :   assert(isa<DILocalVariable>(Variable) && "not a variable");
      93             :   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
      94             :   assert(
      95             :       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
      96             :       "Expected inlined-at fields to agree");
      97             :   return insertInstr(BuildMI(getMF(), getDL(),
      98          10 :                              getTII().get(TargetOpcode::DBG_VALUE),
      99          20 :                              /*IsIndirect*/ false, Reg, Variable, Expr));
     100             : }
     101             : 
     102           0 : MachineInstrBuilder MachineIRBuilderBase::buildIndirectDbgValue(
     103             :     unsigned Reg, const MDNode *Variable, const MDNode *Expr) {
     104             :   assert(isa<DILocalVariable>(Variable) && "not a variable");
     105             :   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
     106             :   assert(
     107             :       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
     108             :       "Expected inlined-at fields to agree");
     109             :   return insertInstr(BuildMI(getMF(), getDL(),
     110           0 :                              getTII().get(TargetOpcode::DBG_VALUE),
     111           0 :                              /*IsIndirect*/ true, Reg, Variable, Expr));
     112             : }
     113             : 
     114             : MachineInstrBuilder
     115           0 : MachineIRBuilderBase::buildFIDbgValue(int FI, const MDNode *Variable,
     116             :                                       const MDNode *Expr) {
     117             :   assert(isa<DILocalVariable>(Variable) && "not a variable");
     118             :   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
     119             :   assert(
     120             :       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
     121             :       "Expected inlined-at fields to agree");
     122           0 :   return buildInstr(TargetOpcode::DBG_VALUE)
     123             :       .addFrameIndex(FI)
     124             :       .addImm(0)
     125             :       .addMetadata(Variable)
     126           0 :       .addMetadata(Expr);
     127             : }
     128             : 
     129           5 : MachineInstrBuilder MachineIRBuilderBase::buildConstDbgValue(
     130             :     const Constant &C, const MDNode *Variable, const MDNode *Expr) {
     131             :   assert(isa<DILocalVariable>(Variable) && "not a variable");
     132             :   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
     133             :   assert(
     134             :       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
     135             :       "Expected inlined-at fields to agree");
     136           5 :   auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
     137             :   if (auto *CI = dyn_cast<ConstantInt>(&C)) {
     138           3 :     if (CI->getBitWidth() > 64)
     139             :       MIB.addCImm(CI);
     140             :     else
     141           3 :       MIB.addImm(CI->getZExtValue());
     142             :   } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
     143             :     MIB.addFPImm(CFP);
     144             :   } else {
     145             :     // Insert %noreg if we didn't find a usable constant and had to drop it.
     146           1 :     MIB.addReg(0U);
     147             :   }
     148             : 
     149           5 :   return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
     150             : }
     151             : 
     152         324 : MachineInstrBuilder MachineIRBuilderBase::buildFrameIndex(unsigned Res,
     153             :                                                           int Idx) {
     154             :   assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
     155         648 :   return buildInstr(TargetOpcode::G_FRAME_INDEX)
     156             :       .addDef(Res)
     157         648 :       .addFrameIndex(Idx);
     158             : }
     159             : 
     160             : MachineInstrBuilder
     161         113 : MachineIRBuilderBase::buildGlobalValue(unsigned Res, const GlobalValue *GV) {
     162             :   assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
     163             :   assert(getMRI()->getType(Res).getAddressSpace() ==
     164             :              GV->getType()->getAddressSpace() &&
     165             :          "address space mismatch");
     166             : 
     167         226 :   return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
     168             :       .addDef(Res)
     169         226 :       .addGlobalAddress(GV);
     170             : }
     171             : 
     172         367 : void MachineIRBuilderBase::validateBinaryOp(unsigned Res, unsigned Op0,
     173             :                                             unsigned Op1) {
     174             :   assert((getMRI()->getType(Res).isScalar() ||
     175             :           getMRI()->getType(Res).isVector()) &&
     176             :          "invalid operand type");
     177             :   assert(getMRI()->getType(Res) == getMRI()->getType(Op0) &&
     178             :          getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch");
     179         367 : }
     180             : 
     181         319 : MachineInstrBuilder MachineIRBuilderBase::buildGEP(unsigned Res, unsigned Op0,
     182             :                                                    unsigned Op1) {
     183             :   assert(getMRI()->getType(Res).isPointer() &&
     184             :          getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch");
     185             :   assert(getMRI()->getType(Op1).isScalar() && "invalid offset type");
     186             : 
     187         638 :   return buildInstr(TargetOpcode::G_GEP)
     188             :       .addDef(Res)
     189             :       .addUse(Op0)
     190         638 :       .addUse(Op1);
     191             : }
     192             : 
     193             : Optional<MachineInstrBuilder>
     194         515 : MachineIRBuilderBase::materializeGEP(unsigned &Res, unsigned Op0,
     195             :                                      const LLT &ValueTy, uint64_t Value) {
     196             :   assert(Res == 0 && "Res is a result argument");
     197             :   assert(ValueTy.isScalar()  && "invalid offset type");
     198             : 
     199         515 :   if (Value == 0) {
     200         429 :     Res = Op0;
     201             :     return None;
     202             :   }
     203             : 
     204         172 :   Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
     205         172 :   unsigned TmpReg = getMRI()->createGenericVirtualRegister(ValueTy);
     206             : 
     207          86 :   buildConstant(TmpReg, Value);
     208         172 :   return buildGEP(Res, Op0, TmpReg);
     209             : }
     210             : 
     211           4 : MachineInstrBuilder MachineIRBuilderBase::buildPtrMask(unsigned Res,
     212             :                                                        unsigned Op0,
     213             :                                                        uint32_t NumBits) {
     214             :   assert(getMRI()->getType(Res).isPointer() &&
     215             :          getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch");
     216             : 
     217           8 :   return buildInstr(TargetOpcode::G_PTR_MASK)
     218             :       .addDef(Res)
     219             :       .addUse(Op0)
     220          12 :       .addImm(NumBits);
     221             : }
     222             : 
     223          64 : MachineInstrBuilder MachineIRBuilderBase::buildBr(MachineBasicBlock &Dest) {
     224         128 :   return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
     225             : }
     226             : 
     227           2 : MachineInstrBuilder MachineIRBuilderBase::buildBrIndirect(unsigned Tgt) {
     228             :   assert(getMRI()->getType(Tgt).isPointer() && "invalid branch destination");
     229           4 :   return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
     230             : }
     231             : 
     232        3724 : MachineInstrBuilder MachineIRBuilderBase::buildCopy(unsigned Res, unsigned Op) {
     233             :   assert(getMRI()->getType(Res) == LLT() || getMRI()->getType(Op) == LLT() ||
     234             :          getMRI()->getType(Res) == getMRI()->getType(Op));
     235        7448 :   return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
     236             : }
     237             : 
     238             : MachineInstrBuilder
     239        1031 : MachineIRBuilderBase::buildConstant(unsigned Res, const ConstantInt &Val) {
     240        2062 :   LLT Ty = getMRI()->getType(Res);
     241             : 
     242             :   assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
     243             : 
     244             :   const ConstantInt *NewVal = &Val;
     245        2062 :   if (Ty.getSizeInBits() != Val.getBitWidth())
     246           0 :     NewVal = ConstantInt::get(getMF().getFunction().getContext(),
     247           0 :                               Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
     248             : 
     249        2062 :   return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
     250             : }
     251             : 
     252         665 : MachineInstrBuilder MachineIRBuilderBase::buildConstant(unsigned Res,
     253             :                                                         int64_t Val) {
     254         665 :   auto IntN = IntegerType::get(getMF().getFunction().getContext(),
     255        1995 :                                getMRI()->getType(Res).getSizeInBits());
     256         665 :   ConstantInt *CI = ConstantInt::get(IntN, Val, true);
     257         665 :   return buildConstant(Res, *CI);
     258             : }
     259             : 
     260             : MachineInstrBuilder
     261          56 : MachineIRBuilderBase::buildFConstant(unsigned Res, const ConstantFP &Val) {
     262             :   assert(getMRI()->getType(Res).isScalar() && "invalid operand type");
     263             : 
     264         112 :   return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
     265             : }
     266             : 
     267           3 : MachineInstrBuilder MachineIRBuilderBase::buildFConstant(unsigned Res,
     268             :                                                          double Val) {
     269           6 :   LLT DstTy = getMRI()->getType(Res);
     270           3 :   auto &Ctx = getMF().getFunction().getContext();
     271             :   auto *CFP =
     272           6 :       ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits()));
     273           3 :   return buildFConstant(Res, *CFP);
     274             : }
     275             : 
     276          32 : MachineInstrBuilder MachineIRBuilderBase::buildBrCond(unsigned Tst,
     277             :                                                       MachineBasicBlock &Dest) {
     278             :   assert(getMRI()->getType(Tst).isScalar() && "invalid operand type");
     279             : 
     280          64 :   return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
     281             : }
     282             : 
     283         586 : MachineInstrBuilder MachineIRBuilderBase::buildLoad(unsigned Res, unsigned Addr,
     284             :                                                     MachineMemOperand &MMO) {
     285         586 :   return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO);
     286             : }
     287             : 
     288             : MachineInstrBuilder
     289         586 : MachineIRBuilderBase::buildLoadInstr(unsigned Opcode, unsigned Res,
     290             :                                      unsigned Addr, MachineMemOperand &MMO) {
     291             :   assert(getMRI()->getType(Res).isValid() && "invalid operand type");
     292             :   assert(getMRI()->getType(Addr).isPointer() && "invalid operand type");
     293             : 
     294        1172 :   return buildInstr(Opcode)
     295             :       .addDef(Res)
     296             :       .addUse(Addr)
     297        1172 :       .addMemOperand(&MMO);
     298             : }
     299             : 
     300         420 : MachineInstrBuilder MachineIRBuilderBase::buildStore(unsigned Val,
     301             :                                                      unsigned Addr,
     302             :                                                      MachineMemOperand &MMO) {
     303             :   assert(getMRI()->getType(Val).isValid() && "invalid operand type");
     304             :   assert(getMRI()->getType(Addr).isPointer() && "invalid operand type");
     305             : 
     306         840 :   return buildInstr(TargetOpcode::G_STORE)
     307             :       .addUse(Val)
     308             :       .addUse(Addr)
     309         840 :       .addMemOperand(&MMO);
     310             : }
     311             : 
     312           9 : MachineInstrBuilder MachineIRBuilderBase::buildUAdde(unsigned Res,
     313             :                                                      unsigned CarryOut,
     314             :                                                      unsigned Op0, unsigned Op1,
     315             :                                                      unsigned CarryIn) {
     316             :   assert(getMRI()->getType(Res).isScalar() && "invalid operand type");
     317             :   assert(getMRI()->getType(Res) == getMRI()->getType(Op0) &&
     318             :          getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch");
     319             :   assert(getMRI()->getType(CarryOut).isScalar() && "invalid operand type");
     320             :   assert(getMRI()->getType(CarryOut) == getMRI()->getType(CarryIn) &&
     321             :          "type mismatch");
     322             : 
     323          18 :   return buildInstr(TargetOpcode::G_UADDE)
     324             :       .addDef(Res)
     325             :       .addDef(CarryOut)
     326             :       .addUse(Op0)
     327             :       .addUse(Op1)
     328          18 :       .addUse(CarryIn);
     329             : }
     330             : 
     331         131 : MachineInstrBuilder MachineIRBuilderBase::buildAnyExt(unsigned Res,
     332             :                                                       unsigned Op) {
     333         131 :   validateTruncExt(Res, Op, true);
     334         262 :   return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
     335             : }
     336             : 
     337          25 : MachineInstrBuilder MachineIRBuilderBase::buildSExt(unsigned Res, unsigned Op) {
     338          25 :   validateTruncExt(Res, Op, true);
     339          50 :   return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
     340             : }
     341             : 
     342          26 : MachineInstrBuilder MachineIRBuilderBase::buildZExt(unsigned Res, unsigned Op) {
     343          26 :   validateTruncExt(Res, Op, true);
     344          52 :   return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
     345             : }
     346             : 
     347         550 : MachineInstrBuilder MachineIRBuilderBase::buildExtOrTrunc(unsigned ExtOpc,
     348             :                                                           unsigned Res,
     349             :                                                           unsigned Op) {
     350             :   assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
     351             :           TargetOpcode::G_SEXT == ExtOpc) &&
     352             :          "Expecting Extending Opc");
     353             :   assert(getMRI()->getType(Res).isScalar() ||
     354             :          getMRI()->getType(Res).isVector());
     355             :   assert(getMRI()->getType(Res).isScalar() == getMRI()->getType(Op).isScalar());
     356             : 
     357             :   unsigned Opcode = TargetOpcode::COPY;
     358        1650 :   if (getMRI()->getType(Res).getSizeInBits() >
     359         550 :       getMRI()->getType(Op).getSizeInBits())
     360             :     Opcode = ExtOpc;
     361         992 :   else if (getMRI()->getType(Res).getSizeInBits() <
     362         496 :            getMRI()->getType(Op).getSizeInBits())
     363             :     Opcode = TargetOpcode::G_TRUNC;
     364             :   else
     365             :     assert(getMRI()->getType(Res) == getMRI()->getType(Op));
     366             : 
     367        1100 :   return buildInstr(Opcode).addDef(Res).addUse(Op);
     368             : }
     369             : 
     370           5 : MachineInstrBuilder MachineIRBuilderBase::buildSExtOrTrunc(unsigned Res,
     371             :                                                            unsigned Op) {
     372           5 :   return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
     373             : }
     374             : 
     375           4 : MachineInstrBuilder MachineIRBuilderBase::buildZExtOrTrunc(unsigned Res,
     376             :                                                            unsigned Op) {
     377           4 :   return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
     378             : }
     379             : 
     380         541 : MachineInstrBuilder MachineIRBuilderBase::buildAnyExtOrTrunc(unsigned Res,
     381             :                                                              unsigned Op) {
     382         541 :   return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
     383             : }
     384             : 
     385          26 : MachineInstrBuilder MachineIRBuilderBase::buildCast(unsigned Dst,
     386             :                                                     unsigned Src) {
     387          26 :   LLT SrcTy = getMRI()->getType(Src);
     388             :   LLT DstTy = getMRI()->getType(Dst);
     389             :   if (SrcTy == DstTy)
     390           7 :     return buildCopy(Dst, Src);
     391             : 
     392             :   unsigned Opcode;
     393             :   if (SrcTy.isPointer() && DstTy.isScalar())
     394             :     Opcode = TargetOpcode::G_PTRTOINT;
     395             :   else if (DstTy.isPointer() && SrcTy.isScalar())
     396             :     Opcode = TargetOpcode::G_INTTOPTR;
     397             :   else {
     398             :     assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
     399             :     Opcode = TargetOpcode::G_BITCAST;
     400             :   }
     401             : 
     402          38 :   return buildInstr(Opcode).addDef(Dst).addUse(Src);
     403             : }
     404             : 
     405             : MachineInstrBuilder
     406         367 : MachineIRBuilderBase::buildExtract(unsigned Res, unsigned Src, uint64_t Index) {
     407             : #ifndef NDEBUG
     408             :   assert(getMRI()->getType(Src).isValid() && "invalid operand type");
     409             :   assert(getMRI()->getType(Res).isValid() && "invalid operand type");
     410             :   assert(Index + getMRI()->getType(Res).getSizeInBits() <=
     411             :              getMRI()->getType(Src).getSizeInBits() &&
     412             :          "extracting off end of register");
     413             : #endif
     414             : 
     415        1101 :   if (getMRI()->getType(Res).getSizeInBits() ==
     416         367 :       getMRI()->getType(Src).getSizeInBits()) {
     417             :     assert(Index == 0 && "insertion past the end of a register");
     418           2 :     return buildCast(Res, Src);
     419             :   }
     420             : 
     421         730 :   return buildInstr(TargetOpcode::G_EXTRACT)
     422             :       .addDef(Res)
     423             :       .addUse(Src)
     424         730 :       .addImm(Index);
     425             : }
     426             : 
     427           1 : void MachineIRBuilderBase::buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
     428             :                                          ArrayRef<uint64_t> Indices) {
     429             : #ifndef NDEBUG
     430             :   assert(Ops.size() == Indices.size() && "incompatible args");
     431             :   assert(!Ops.empty() && "invalid trivial sequence");
     432             :   assert(std::is_sorted(Indices.begin(), Indices.end()) &&
     433             :          "sequence offsets must be in ascending order");
     434             : 
     435             :   assert(getMRI()->getType(Res).isValid() && "invalid operand type");
     436             :   for (auto Op : Ops)
     437             :     assert(getMRI()->getType(Op).isValid() && "invalid operand type");
     438             : #endif
     439             : 
     440           2 :   LLT ResTy = getMRI()->getType(Res);
     441           2 :   LLT OpTy = getMRI()->getType(Ops[0]);
     442           1 :   unsigned OpSize = OpTy.getSizeInBits();
     443             :   bool MaybeMerge = true;
     444           9 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     445           8 :     if (getMRI()->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
     446             :       MaybeMerge = false;
     447             :       break;
     448             :     }
     449             :   }
     450             : 
     451           1 :   if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
     452           1 :     buildMerge(Res, Ops);
     453           1 :     return;
     454             :   }
     455             : 
     456           0 :   unsigned ResIn = getMRI()->createGenericVirtualRegister(ResTy);
     457           0 :   buildUndef(ResIn);
     458             : 
     459           0 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     460           0 :     unsigned ResOut = i + 1 == Ops.size()
     461           0 :                           ? Res
     462           0 :                           : getMRI()->createGenericVirtualRegister(ResTy);
     463           0 :     buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
     464             :     ResIn = ResOut;
     465             :   }
     466             : }
     467             : 
     468         117 : MachineInstrBuilder MachineIRBuilderBase::buildUndef(unsigned Res) {
     469         234 :   return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
     470             : }
     471             : 
     472         271 : MachineInstrBuilder MachineIRBuilderBase::buildMerge(unsigned Res,
     473             :                                                      ArrayRef<unsigned> Ops) {
     474             : 
     475             : #ifndef NDEBUG
     476             :   assert(!Ops.empty() && "invalid trivial sequence");
     477             :   LLT Ty = getMRI()->getType(Ops[0]);
     478             :   for (auto Reg : Ops)
     479             :     assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list");
     480             :   assert(Ops.size() * getMRI()->getType(Ops[0]).getSizeInBits() ==
     481             :              getMRI()->getType(Res).getSizeInBits() &&
     482             :          "input operands do not cover output register");
     483             : #endif
     484             : 
     485         271 :   if (Ops.size() == 1)
     486           5 :     return buildCast(Res, Ops[0]);
     487             : 
     488         266 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
     489             :   MIB.addDef(Res);
     490        1626 :   for (unsigned i = 0; i < Ops.size(); ++i)
     491         680 :     MIB.addUse(Ops[i]);
     492         266 :   return MIB;
     493             : }
     494             : 
     495         328 : MachineInstrBuilder MachineIRBuilderBase::buildUnmerge(ArrayRef<unsigned> Res,
     496             :                                                        unsigned Op) {
     497             : 
     498             : #ifndef NDEBUG
     499             :   assert(!Res.empty() && "invalid trivial sequence");
     500             :   LLT Ty = getMRI()->getType(Res[0]);
     501             :   for (auto Reg : Res)
     502             :     assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list");
     503             :   assert(Res.size() * getMRI()->getType(Res[0]).getSizeInBits() ==
     504             :              getMRI()->getType(Op).getSizeInBits() &&
     505             :          "input operands do not cover output register");
     506             : #endif
     507             : 
     508         328 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
     509        1914 :   for (unsigned i = 0; i < Res.size(); ++i)
     510        1586 :     MIB.addDef(Res[i]);
     511             :   MIB.addUse(Op);
     512         328 :   return MIB;
     513             : }
     514             : 
     515         255 : MachineInstrBuilder MachineIRBuilderBase::buildInsert(unsigned Res,
     516             :                                                       unsigned Src, unsigned Op,
     517             :                                                       unsigned Index) {
     518             :   assert(Index + getMRI()->getType(Op).getSizeInBits() <=
     519             :              getMRI()->getType(Res).getSizeInBits() &&
     520             :          "insertion past the end of a register");
     521             : 
     522         765 :   if (getMRI()->getType(Res).getSizeInBits() ==
     523         255 :       getMRI()->getType(Op).getSizeInBits()) {
     524           1 :     return buildCast(Res, Op);
     525             :   }
     526             : 
     527         508 :   return buildInstr(TargetOpcode::G_INSERT)
     528             :       .addDef(Res)
     529             :       .addUse(Src)
     530             :       .addUse(Op)
     531         508 :       .addImm(Index);
     532             : }
     533             : 
     534          12 : MachineInstrBuilder MachineIRBuilderBase::buildIntrinsic(Intrinsic::ID ID,
     535             :                                                          unsigned Res,
     536             :                                                          bool HasSideEffects) {
     537             :   auto MIB =
     538             :       buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
     539          12 :                                 : TargetOpcode::G_INTRINSIC);
     540          12 :   if (Res)
     541             :     MIB.addDef(Res);
     542             :   MIB.addIntrinsicID(ID);
     543          12 :   return MIB;
     544             : }
     545             : 
     546         366 : MachineInstrBuilder MachineIRBuilderBase::buildTrunc(unsigned Res,
     547             :                                                      unsigned Op) {
     548         366 :   validateTruncExt(Res, Op, false);
     549         732 :   return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
     550             : }
     551             : 
     552           1 : MachineInstrBuilder MachineIRBuilderBase::buildFPTrunc(unsigned Res,
     553             :                                                        unsigned Op) {
     554           1 :   validateTruncExt(Res, Op, false);
     555           2 :   return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
     556             : }
     557             : 
     558          96 : MachineInstrBuilder MachineIRBuilderBase::buildICmp(CmpInst::Predicate Pred,
     559             :                                                     unsigned Res, unsigned Op0,
     560             :                                                     unsigned Op1) {
     561             : #ifndef NDEBUG
     562             :   assert(getMRI()->getType(Op0) == getMRI()->getType(Op0) && "type mismatch");
     563             :   assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
     564             :   if (getMRI()->getType(Op0).isScalar() || getMRI()->getType(Op0).isPointer())
     565             :     assert(getMRI()->getType(Res).isScalar() && "type mismatch");
     566             :   else
     567             :     assert(getMRI()->getType(Res).isVector() &&
     568             :            getMRI()->getType(Res).getNumElements() ==
     569             :                getMRI()->getType(Op0).getNumElements() &&
     570             :            "type mismatch");
     571             : #endif
     572             : 
     573         192 :   return buildInstr(TargetOpcode::G_ICMP)
     574             :       .addDef(Res)
     575             :       .addPredicate(Pred)
     576             :       .addUse(Op0)
     577         192 :       .addUse(Op1);
     578             : }
     579             : 
     580           7 : MachineInstrBuilder MachineIRBuilderBase::buildFCmp(CmpInst::Predicate Pred,
     581             :                                                     unsigned Res, unsigned Op0,
     582             :                                                     unsigned Op1) {
     583             : #ifndef NDEBUG
     584             :   assert((getMRI()->getType(Op0).isScalar() ||
     585             :           getMRI()->getType(Op0).isVector()) &&
     586             :          "invalid operand type");
     587             :   assert(getMRI()->getType(Op0) == getMRI()->getType(Op1) && "type mismatch");
     588             :   assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
     589             :   if (getMRI()->getType(Op0).isScalar())
     590             :     assert(getMRI()->getType(Res).isScalar() && "type mismatch");
     591             :   else
     592             :     assert(getMRI()->getType(Res).isVector() &&
     593             :            getMRI()->getType(Res).getNumElements() ==
     594             :                getMRI()->getType(Op0).getNumElements() &&
     595             :            "type mismatch");
     596             : #endif
     597             : 
     598          14 :   return buildInstr(TargetOpcode::G_FCMP)
     599             :       .addDef(Res)
     600             :       .addPredicate(Pred)
     601             :       .addUse(Op0)
     602          14 :       .addUse(Op1);
     603             : }
     604             : 
     605           6 : MachineInstrBuilder MachineIRBuilderBase::buildSelect(unsigned Res,
     606             :                                                       unsigned Tst,
     607             :                                                       unsigned Op0,
     608             :                                                       unsigned Op1) {
     609             : #ifndef NDEBUG
     610             :   LLT ResTy = getMRI()->getType(Res);
     611             :   assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
     612             :          "invalid operand type");
     613             :   assert(ResTy == getMRI()->getType(Op0) && ResTy == getMRI()->getType(Op1) &&
     614             :          "type mismatch");
     615             :   if (ResTy.isScalar() || ResTy.isPointer())
     616             :     assert(getMRI()->getType(Tst).isScalar() && "type mismatch");
     617             :   else
     618             :     assert((getMRI()->getType(Tst).isScalar() ||
     619             :             (getMRI()->getType(Tst).isVector() &&
     620             :              getMRI()->getType(Tst).getNumElements() ==
     621             :                  getMRI()->getType(Op0).getNumElements())) &&
     622             :            "type mismatch");
     623             : #endif
     624             : 
     625          12 :   return buildInstr(TargetOpcode::G_SELECT)
     626             :       .addDef(Res)
     627             :       .addUse(Tst)
     628             :       .addUse(Op0)
     629          12 :       .addUse(Op1);
     630             : }
     631             : 
     632             : MachineInstrBuilder
     633          19 : MachineIRBuilderBase::buildInsertVectorElement(unsigned Res, unsigned Val,
     634             :                                                unsigned Elt, unsigned Idx) {
     635             : #ifndef NDEBUG
     636             :   LLT ResTy = getMRI()->getType(Res);
     637             :   LLT ValTy = getMRI()->getType(Val);
     638             :   LLT EltTy = getMRI()->getType(Elt);
     639             :   LLT IdxTy = getMRI()->getType(Idx);
     640             :   assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type");
     641             :   assert(IdxTy.isScalar() && "invalid operand type");
     642             :   assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch");
     643             :   assert(ResTy.getElementType() == EltTy && "type mismatch");
     644             : #endif
     645             : 
     646          38 :   return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT)
     647             :       .addDef(Res)
     648             :       .addUse(Val)
     649             :       .addUse(Elt)
     650          38 :       .addUse(Idx);
     651             : }
     652             : 
     653             : MachineInstrBuilder
     654          20 : MachineIRBuilderBase::buildExtractVectorElement(unsigned Res, unsigned Val,
     655             :                                                 unsigned Idx) {
     656             : #ifndef NDEBUG
     657             :   LLT ResTy = getMRI()->getType(Res);
     658             :   LLT ValTy = getMRI()->getType(Val);
     659             :   LLT IdxTy = getMRI()->getType(Idx);
     660             :   assert(ValTy.isVector() && "invalid operand type");
     661             :   assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type");
     662             :   assert(IdxTy.isScalar() && "invalid operand type");
     663             :   assert(ValTy.getElementType() == ResTy && "type mismatch");
     664             : #endif
     665             : 
     666          40 :   return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
     667             :       .addDef(Res)
     668             :       .addUse(Val)
     669          40 :       .addUse(Idx);
     670             : }
     671             : 
     672             : MachineInstrBuilder
     673           2 : MachineIRBuilderBase::buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr,
     674             :                                          unsigned CmpVal, unsigned NewVal,
     675             :                                          MachineMemOperand &MMO) {
     676             : #ifndef NDEBUG
     677             :   LLT OldValResTy = getMRI()->getType(OldValRes);
     678             :   LLT AddrTy = getMRI()->getType(Addr);
     679             :   LLT CmpValTy = getMRI()->getType(CmpVal);
     680             :   LLT NewValTy = getMRI()->getType(NewVal);
     681             :   assert(OldValResTy.isScalar() && "invalid operand type");
     682             :   assert(AddrTy.isPointer() && "invalid operand type");
     683             :   assert(CmpValTy.isValid() && "invalid operand type");
     684             :   assert(NewValTy.isValid() && "invalid operand type");
     685             :   assert(OldValResTy == CmpValTy && "type mismatch");
     686             :   assert(OldValResTy == NewValTy && "type mismatch");
     687             : #endif
     688             : 
     689           4 :   return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
     690             :       .addDef(OldValRes)
     691             :       .addUse(Addr)
     692             :       .addUse(CmpVal)
     693             :       .addUse(NewVal)
     694           4 :       .addMemOperand(&MMO);
     695             : }
     696             : 
     697         549 : void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src,
     698             :                                             bool IsExtend) {
     699             : #ifndef NDEBUG
     700             :   LLT SrcTy = getMRI()->getType(Src);
     701             :   LLT DstTy = getMRI()->getType(Dst);
     702             : 
     703             :   if (DstTy.isVector()) {
     704             :     assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
     705             :     assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
     706             :            "different number of elements in a trunc/ext");
     707             :   } else
     708             :     assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
     709             : 
     710             :   if (IsExtend)
     711             :     assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
     712             :            "invalid narrowing extend");
     713             :   else
     714             :     assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
     715             :            "invalid widening trunc");
     716             : #endif
     717         549 : }

Generated by: LCOV version 1.13