LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - MachineIRBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 196 203 96.6 %
Date: 2018-02-25 19:55:18 Functions: 56 58 96.6 %
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        4036 : void MachineIRBuilder::setMF(MachineFunction &MF) {
      26        4036 :   this->MF = &MF;
      27        4036 :   this->MBB = nullptr;
      28        4036 :   this->MRI = &MF.getRegInfo();
      29        4036 :   this->TII = MF.getSubtarget().getInstrInfo();
      30        8072 :   this->DL = DebugLoc();
      31        4036 :   this->II = MachineBasicBlock::iterator();
      32             :   this->InsertedInstr = nullptr;
      33        4036 : }
      34             : 
      35        4741 : void MachineIRBuilder::setMBB(MachineBasicBlock &MBB) {
      36        4741 :   this->MBB = &MBB;
      37        4741 :   this->II = MBB.end();
      38             :   assert(&getMF() == MBB.getParent() &&
      39             :          "Basic block is in a different function");
      40        4741 : }
      41             : 
      42        1154 : void MachineIRBuilder::setInstr(MachineInstr &MI) {
      43             :   assert(MI.getParent() && "Instruction is not part of a basic block");
      44        1154 :   setMBB(*MI.getParent());
      45        1154 :   this->II = MI.getIterator();
      46        1154 : }
      47             : 
      48          35 : void MachineIRBuilder::setInsertPt(MachineBasicBlock &MBB,
      49             :                                    MachineBasicBlock::iterator II) {
      50             :   assert(MBB.getParent() == &getMF() &&
      51             :          "Basic block is in a different function");
      52          35 :   this->MBB = &MBB;
      53          35 :   this->II = II;
      54          35 : }
      55             : 
      56        1166 : void MachineIRBuilder::recordInsertions(
      57             :     std::function<void(MachineInstr *)> Inserted) {
      58        1166 :   InsertedInstr = std::move(Inserted);
      59        1166 : }
      60             : 
      61          32 : void MachineIRBuilder::stopRecordingInsertions() {
      62             :   InsertedInstr = nullptr;
      63          32 : }
      64             : 
      65             : //------------------------------------------------------------------------------
      66             : // Build instruction variants.
      67             : //------------------------------------------------------------------------------
      68             : 
      69       10915 : MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) {
      70       10915 :   return insertInstr(buildInstrNoInsert(Opcode));
      71             : }
      72             : 
      73       12281 : MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
      74       24562 :   MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
      75       12281 :   return MIB;
      76             : }
      77             : 
      78             : 
      79       12165 : MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
      80       12165 :   getMBB().insert(getInsertPt(), MIB);
      81       12165 :   if (InsertedInstr)
      82             :     InsertedInstr(MIB);
      83       12165 :   return MIB;
      84             : }
      85             : 
      86             : MachineInstrBuilder
      87          10 : MachineIRBuilder::buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
      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          10 :   return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
      94          20 :                              /*IsIndirect*/ false, Reg, Variable, Expr));
      95             : }
      96             : 
      97             : MachineInstrBuilder
      98           0 : MachineIRBuilder::buildIndirectDbgValue(unsigned Reg, const MDNode *Variable,
      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           0 :   return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
     105           0 :                              /*IsIndirect*/ true, Reg, Variable, Expr));
     106             : }
     107             : 
     108           0 : MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
     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           0 :   return buildInstr(TargetOpcode::DBG_VALUE)
     116             :       .addFrameIndex(FI)
     117             :       .addImm(0)
     118             :       .addMetadata(Variable)
     119           0 :       .addMetadata(Expr);
     120             : }
     121             : 
     122           5 : MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
     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           5 :   auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
     130             :   if (auto *CI = dyn_cast<ConstantInt>(&C)) {
     131           3 :     if (CI->getBitWidth() > 64)
     132             :       MIB.addCImm(CI);
     133             :     else
     134           3 :       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           1 :     MIB.addReg(0U);
     140             :   }
     141             : 
     142           5 :   return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
     143             : }
     144             : 
     145         324 : MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
     146             :   assert(MRI->getType(Res).isPointer() && "invalid operand type");
     147         648 :   return buildInstr(TargetOpcode::G_FRAME_INDEX)
     148             :       .addDef(Res)
     149         648 :       .addFrameIndex(Idx);
     150             : }
     151             : 
     152         113 : MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
     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         226 :   return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
     160             :       .addDef(Res)
     161         226 :       .addGlobalAddress(GV);
     162             : }
     163             : 
     164         343 : 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         686 :   return buildInstr(Opcode)
     172             :       .addDef(Res)
     173             :       .addUse(Op0)
     174         686 :       .addUse(Op1);
     175             : }
     176             : 
     177          86 : MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
     178             :                                                unsigned Op1) {
     179          86 :   return buildBinaryOp(TargetOpcode::G_ADD, Res, Op0, Op1);
     180             : }
     181             : 
     182         250 : MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0,
     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         500 :   return buildInstr(TargetOpcode::G_GEP)
     189             :       .addDef(Res)
     190             :       .addUse(Op0)
     191         500 :       .addUse(Op1);
     192             : }
     193             : 
     194             : Optional<MachineInstrBuilder>
     195          34 : 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          34 :   if (Value == 0) {
     201          17 :     Res = Op0;
     202             :     return None;
     203             :   }
     204             : 
     205          17 :   Res = MRI->createGenericVirtualRegister(MRI->getType(Op0));
     206          17 :   unsigned TmpReg = MRI->createGenericVirtualRegister(ValueTy);
     207             : 
     208          17 :   buildConstant(TmpReg, Value);
     209          34 :   return buildGEP(Res, Op0, TmpReg);
     210             : }
     211             : 
     212           4 : MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0,
     213             :                                                    uint32_t NumBits) {
     214             :   assert(MRI->getType(Res).isPointer() &&
     215             :          MRI->getType(Res) == MRI->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          28 : MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
     224             :                                                unsigned Op1) {
     225          28 :   return buildBinaryOp(TargetOpcode::G_SUB, Res, Op0, Op1);
     226             : }
     227             : 
     228          45 : MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
     229             :                                                unsigned Op1) {
     230          45 :   return buildBinaryOp(TargetOpcode::G_MUL, Res, Op0, Op1);
     231             : }
     232             : 
     233         171 : MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0,
     234             :                                                unsigned Op1) {
     235         171 :   return buildBinaryOp(TargetOpcode::G_AND, Res, Op0, Op1);
     236             : }
     237             : 
     238          13 : MachineInstrBuilder MachineIRBuilder::buildOr(unsigned Res, unsigned Op0,
     239             :                                               unsigned Op1) {
     240          13 :   return buildBinaryOp(TargetOpcode::G_OR, Res, Op0, Op1);
     241             : }
     242             : 
     243          61 : MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
     244         122 :   return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
     245             : }
     246             : 
     247           2 : MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) {
     248             :   assert(MRI->getType(Tgt).isPointer() && "invalid branch destination");
     249           4 :   return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
     250             : }
     251             : 
     252        3545 : MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
     253             :   assert(MRI->getType(Res) == LLT() || MRI->getType(Op) == LLT() ||
     254             :          MRI->getType(Res) == MRI->getType(Op));
     255        7090 :   return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
     256             : }
     257             : 
     258         916 : MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
     259             :                                                     const ConstantInt &Val) {
     260         916 :   LLT Ty = MRI->getType(Res);
     261             : 
     262             :   assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
     263             : 
     264             :   const ConstantInt *NewVal = &Val;
     265        1832 :   if (Ty.getSizeInBits() != Val.getBitWidth())
     266          38 :     NewVal = ConstantInt::get(MF->getFunction().getContext(),
     267          76 :                               Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
     268             : 
     269        1832 :   return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
     270             : }
     271             : 
     272         568 : MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
     273             :                                                     int64_t Val) {
     274         568 :   auto IntN = IntegerType::get(MF->getFunction().getContext(),
     275        1136 :                                MRI->getType(Res).getSizeInBits());
     276         568 :   ConstantInt *CI = ConstantInt::get(IntN, Val, true);
     277         568 :   return buildConstant(Res, *CI);
     278             : }
     279             : 
     280          54 : MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
     281             :                                                      const ConstantFP &Val) {
     282             :   assert(MRI->getType(Res).isScalar() && "invalid operand type");
     283             : 
     284         108 :   return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
     285             : }
     286             : 
     287          30 : MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
     288             :                                                   MachineBasicBlock &Dest) {
     289             :   assert(MRI->getType(Tst).isScalar() && "invalid operand type");
     290             : 
     291          60 :   return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
     292             : }
     293             : 
     294         566 : MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
     295             :                                                 MachineMemOperand &MMO) {
     296             :   assert(MRI->getType(Res).isValid() && "invalid operand type");
     297             :   assert(MRI->getType(Addr).isPointer() && "invalid operand type");
     298             : 
     299        1132 :   return buildInstr(TargetOpcode::G_LOAD)
     300             :       .addDef(Res)
     301             :       .addUse(Addr)
     302        1132 :       .addMemOperand(&MMO);
     303             : }
     304             : 
     305         391 : MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
     306             :                                                  MachineMemOperand &MMO) {
     307             :   assert(MRI->getType(Val).isValid() && "invalid operand type");
     308             :   assert(MRI->getType(Addr).isPointer() && "invalid operand type");
     309             : 
     310         782 :   return buildInstr(TargetOpcode::G_STORE)
     311             :       .addUse(Val)
     312             :       .addUse(Addr)
     313         782 :       .addMemOperand(&MMO);
     314             : }
     315             : 
     316           9 : MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
     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          18 :   return buildInstr(TargetOpcode::G_UADDE)
     327             :       .addDef(Res)
     328             :       .addDef(CarryOut)
     329             :       .addUse(Op0)
     330             :       .addUse(Op1)
     331          18 :       .addUse(CarryIn);
     332             : }
     333             : 
     334         264 : MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
     335         264 :   validateTruncExt(Res, Op, true);
     336         528 :   return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
     337             : }
     338             : 
     339          35 : MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
     340          35 :   validateTruncExt(Res, Op, true);
     341          70 :   return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
     342             : }
     343             : 
     344          31 : MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
     345          31 :   validateTruncExt(Res, Op, true);
     346          62 :   return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
     347             : }
     348             : 
     349             : MachineInstrBuilder
     350         511 : 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         511 :   if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
     359             :     Opcode = ExtOpc;
     360         466 :   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        1022 :   return buildInstr(Opcode).addDef(Res).addUse(Op);
     366             : }
     367             : 
     368           5 : MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
     369             :                                                        unsigned Op) {
     370           5 :   return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
     371             : }
     372             : 
     373           4 : MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res,
     374             :                                                        unsigned Op) {
     375           4 :   return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
     376             : }
     377             : 
     378         502 : MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(unsigned Res,
     379             :                                                          unsigned Op) {
     380         502 :   return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
     381             : }
     382             : 
     383          14 : MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
     384          14 :   LLT SrcTy = MRI->getType(Src);
     385          14 :   LLT DstTy = MRI->getType(Dst);
     386             :   if (SrcTy == DstTy)
     387           7 :     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          14 :   return buildInstr(Opcode).addDef(Dst).addUse(Src);
     400             : }
     401             : 
     402          57 : MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src,
     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          57 :   if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) {
     413             :     assert(Index == 0 && "insertion past the end of a register");
     414           0 :     return buildCast(Res, Src);
     415             :   }
     416             : 
     417         114 :   return buildInstr(TargetOpcode::G_EXTRACT)
     418             :       .addDef(Res)
     419             :       .addUse(Src)
     420         114 :       .addImm(Index);
     421             : }
     422             : 
     423           9 : void MachineIRBuilder::buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
     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           9 :   LLT ResTy = MRI->getType(Res);
     437           9 :   LLT OpTy = MRI->getType(Ops[0]);
     438           9 :   unsigned OpSize = OpTy.getSizeInBits();
     439             :   bool MaybeMerge = true;
     440          33 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     441          60 :     if (MRI->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
     442             :       MaybeMerge = false;
     443             :       break;
     444             :     }
     445             :   }
     446             : 
     447           9 :   if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
     448           1 :     buildMerge(Res, Ops);
     449           1 :     return;
     450             :   }
     451             : 
     452           8 :   unsigned ResIn = MRI->createGenericVirtualRegister(ResTy);
     453           8 :   buildUndef(ResIn);
     454             : 
     455          18 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     456             :     unsigned ResOut =
     457          18 :         i + 1 == Ops.size() ? Res : MRI->createGenericVirtualRegister(ResTy);
     458          36 :     buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
     459             :     ResIn = ResOut;
     460             :   }
     461             : }
     462             : 
     463          89 : MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) {
     464         178 :   return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
     465             : }
     466             : 
     467         276 : MachineInstrBuilder MachineIRBuilder::buildMerge(unsigned Res,
     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         276 :   if (Ops.size() == 1)
     481           7 :     return buildCast(Res, Ops[0]);
     482             : 
     483         269 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
     484             :   MIB.addDef(Res);
     485        1641 :   for (unsigned i = 0; i < Ops.size(); ++i)
     486         686 :     MIB.addUse(Ops[i]);
     487         269 :   return MIB;
     488             : }
     489             : 
     490         332 : MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res,
     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         332 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
     504        1934 :   for (unsigned i = 0; i < Res.size(); ++i)
     505        1602 :     MIB.addDef(Res[i]);
     506             :   MIB.addUse(Op);
     507         332 :   return MIB;
     508             : }
     509             : 
     510          92 : MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src,
     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          92 :   if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
     517           4 :     return buildCast(Res, Op);
     518             :   }
     519             : 
     520         176 :   return buildInstr(TargetOpcode::G_INSERT)
     521             :       .addDef(Res)
     522             :       .addUse(Src)
     523             :       .addUse(Op)
     524         176 :       .addImm(Index);
     525             : }
     526             : 
     527           9 : MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
     528             :                                                      unsigned Res,
     529             :                                                      bool HasSideEffects) {
     530             :   auto MIB =
     531             :       buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
     532           9 :                                 : TargetOpcode::G_INTRINSIC);
     533           9 :   if (Res)
     534             :     MIB.addDef(Res);
     535             :   MIB.addIntrinsicID(ID);
     536           9 :   return MIB;
     537             : }
     538             : 
     539         550 : MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
     540         550 :   validateTruncExt(Res, Op, false);
     541        1100 :   return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
     542             : }
     543             : 
     544           1 : MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
     545           1 :   validateTruncExt(Res, Op, false);
     546           2 :   return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
     547             : }
     548             : 
     549         117 : MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
     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         234 :   return buildInstr(TargetOpcode::G_ICMP)
     565             :       .addDef(Res)
     566             :       .addPredicate(Pred)
     567             :       .addUse(Op0)
     568         234 :       .addUse(Op1);
     569             : }
     570             : 
     571           7 : MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
     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          14 :   return buildInstr(TargetOpcode::G_FCMP)
     589             :       .addDef(Res)
     590             :       .addPredicate(Pred)
     591             :       .addUse(Op0)
     592          14 :       .addUse(Op1);
     593             : }
     594             : 
     595           6 : MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
     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          12 :   return buildInstr(TargetOpcode::G_SELECT)
     614             :       .addDef(Res)
     615             :       .addUse(Tst)
     616             :       .addUse(Op0)
     617          12 :       .addUse(Op1);
     618             : }
     619             : 
     620          19 : MachineInstrBuilder MachineIRBuilder::buildInsertVectorElement(unsigned Res,
     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          38 :   return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT)
     636             :       .addDef(Res)
     637             :       .addUse(Val)
     638             :       .addUse(Elt)
     639          38 :       .addUse(Idx);
     640             : }
     641             : 
     642          20 : MachineInstrBuilder MachineIRBuilder::buildExtractVectorElement(unsigned Res,
     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          40 :   return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
     656             :       .addDef(Res)
     657             :       .addUse(Val)
     658          40 :       .addUse(Idx);
     659             : }
     660             : 
     661             : MachineInstrBuilder
     662           2 : 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           4 :   return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
     679             :       .addDef(OldValRes)
     680             :       .addUse(Addr)
     681             :       .addUse(CmpVal)
     682             :       .addUse(NewVal)
     683           4 :       .addMemOperand(&MMO);
     684             : }
     685             : 
     686         881 : 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         881 : }

Generated by: LCOV version 1.13