LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - MachineIRBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 244 254 96.1 %
Date: 2017-09-14 15:23:50 Functions: 55 57 96.5 %
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/IR/DebugInfo.h"
      19             : #include "llvm/Target/TargetInstrInfo.h"
      20             : #include "llvm/Target/TargetOpcodes.h"
      21             : #include "llvm/Target/TargetSubtargetInfo.h"
      22             : 
      23             : using namespace llvm;
      24             : 
      25        4540 : void MachineIRBuilder::setMF(MachineFunction &MF) {
      26        4540 :   this->MF = &MF;
      27        4540 :   this->MBB = nullptr;
      28        4540 :   this->MRI = &MF.getRegInfo();
      29        4540 :   this->TII = MF.getSubtarget().getInstrInfo();
      30       18160 :   this->DL = DebugLoc();
      31        4540 :   this->II = MachineBasicBlock::iterator();
      32        9080 :   this->InsertedInstr = nullptr;
      33        4540 : }
      34             : 
      35        3782 : void MachineIRBuilder::setMBB(MachineBasicBlock &MBB) {
      36        3782 :   this->MBB = &MBB;
      37        3782 :   this->II = MBB.end();
      38             :   assert(&getMF() == MBB.getParent() &&
      39             :          "Basic block is in a different function");
      40        3782 : }
      41             : 
      42         580 : void MachineIRBuilder::setInstr(MachineInstr &MI) {
      43             :   assert(MI.getParent() && "Instruction is not part of a basic block");
      44         580 :   setMBB(*MI.getParent());
      45        1160 :   this->II = MI.getIterator();
      46         580 : }
      47             : 
      48          27 : void MachineIRBuilder::setInsertPt(MachineBasicBlock &MBB,
      49             :                                    MachineBasicBlock::iterator II) {
      50             :   assert(MBB.getParent() == &getMF() &&
      51             :          "Basic block is in a different function");
      52          27 :   this->MBB = &MBB;
      53          27 :   this->II = II;
      54          27 : }
      55             : 
      56        2186 : void MachineIRBuilder::recordInsertions(
      57             :     std::function<void(MachineInstr *)> Inserted) {
      58        2186 :   InsertedInstr = std::move(Inserted);
      59        2186 : }
      60             : 
      61        2186 : void MachineIRBuilder::stopRecordingInsertions() {
      62        4372 :   InsertedInstr = nullptr;
      63        2186 : }
      64             : 
      65             : //------------------------------------------------------------------------------
      66             : // Build instruction variants.
      67             : //------------------------------------------------------------------------------
      68             : 
      69        8228 : MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) {
      70        8228 :   return insertInstr(buildInstrNoInsert(Opcode));
      71             : }
      72             : 
      73        9414 : MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
      74       28242 :   MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
      75        9414 :   return MIB;
      76             : }
      77             : 
      78             : 
      79        9329 : MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
      80       18658 :   getMBB().insert(getInsertPt(), MIB);
      81       18658 :   if (InsertedInstr)
      82        2531 :     InsertedInstr(MIB);
      83        9329 :   return MIB;
      84             : }
      85             : 
      86             : MachineInstrBuilder
      87           4 : 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           4 :   return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
      94           8 :                              /*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           0 :       .addFrameIndex(FI)
     117           0 :       .addImm(0)
     118           0 :       .addMetadata(Variable)
     119           0 :       .addMetadata(Expr);
     120             : }
     121             : 
     122           3 : 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           3 :   auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
     130           3 :   if (auto *CI = dyn_cast<ConstantInt>(&C)) {
     131           1 :     if (CI->getBitWidth() > 64)
     132             :       MIB.addCImm(CI);
     133             :     else
     134           1 :       MIB.addImm(CI->getZExtValue());
     135           2 :   } 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           9 :   return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
     143             : }
     144             : 
     145         307 : MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
     146             :   assert(MRI->getType(Res).isPointer() && "invalid operand type");
     147         614 :   return buildInstr(TargetOpcode::G_FRAME_INDEX)
     148         307 :       .addDef(Res)
     149         614 :       .addFrameIndex(Idx);
     150             : }
     151             : 
     152          83 : 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         166 :   return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
     160          83 :       .addDef(Res)
     161         166 :       .addGlobalAddress(GV);
     162             : }
     163             : 
     164         170 : 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         340 :   return buildInstr(Opcode)
     172         170 :       .addDef(Res)
     173         170 :       .addUse(Op0)
     174         340 :       .addUse(Op1);
     175             : }
     176             : 
     177          80 : MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
     178             :                                                unsigned Op1) {
     179          80 :   return buildBinaryOp(TargetOpcode::G_ADD, Res, Op0, Op1);
     180             : }
     181             : 
     182         237 : 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         474 :   return buildInstr(TargetOpcode::G_GEP)
     189         237 :       .addDef(Res)
     190         237 :       .addUse(Op0)
     191         474 :       .addUse(Op1);
     192             : }
     193             : 
     194             : Optional<MachineInstrBuilder>
     195          28 : 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          28 :   if (Value == 0) {
     201          14 :     Res = Op0;
     202             :     return None;
     203             :   }
     204             : 
     205          14 :   Res = MRI->createGenericVirtualRegister(MRI->getType(Op0));
     206          14 :   unsigned TmpReg = MRI->createGenericVirtualRegister(ValueTy);
     207             : 
     208          14 :   buildConstant(TmpReg, Value);
     209          28 :   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           4 :       .addDef(Res)
     219           4 :       .addUse(Op0)
     220          12 :       .addImm(NumBits);
     221             : }
     222             : 
     223          27 : MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
     224             :                                                unsigned Op1) {
     225          27 :   return buildBinaryOp(TargetOpcode::G_SUB, Res, Op0, Op1);
     226             : }
     227             : 
     228          41 : MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
     229             :                                                unsigned Op1) {
     230          41 :   return buildBinaryOp(TargetOpcode::G_MUL, Res, Op0, Op1);
     231             : }
     232             : 
     233          12 : MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0,
     234             :                                                unsigned Op1) {
     235          12 :   return buildBinaryOp(TargetOpcode::G_AND, Res, Op0, Op1);
     236             : }
     237             : 
     238          10 : MachineInstrBuilder MachineIRBuilder::buildOr(unsigned Res, unsigned Op0,
     239             :                                               unsigned Op1) {
     240          10 :   return buildBinaryOp(TargetOpcode::G_OR, Res, Op0, Op1);
     241             : }
     242             : 
     243          52 : MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
     244         104 :   return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
     245             : }
     246             : 
     247           1 : MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) {
     248             :   assert(MRI->getType(Tgt).isPointer() && "invalid branch destination");
     249           2 :   return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
     250             : }
     251             : 
     252        3185 : 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        9555 :   return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
     256             : }
     257             : 
     258         576 : MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
     259             :                                                     const ConstantInt &Val) {
     260         576 :   LLT Ty = MRI->getType(Res);
     261             : 
     262             :   assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
     263             : 
     264         576 :   const ConstantInt *NewVal = &Val;
     265        1152 :   if (Ty.getSizeInBits() != Val.getBitWidth())
     266          25 :     NewVal = ConstantInt::get(MF->getFunction()->getContext(),
     267          50 :                               Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
     268             : 
     269        1728 :   return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
     270             : }
     271             : 
     272         297 : MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
     273             :                                                     int64_t Val) {
     274         297 :   auto IntN = IntegerType::get(MF->getFunction()->getContext(),
     275         594 :                                MRI->getType(Res).getSizeInBits());
     276         297 :   ConstantInt *CI = ConstantInt::get(IntN, Val, true);
     277         297 :   return buildConstant(Res, *CI);
     278             : }
     279             : 
     280          18 : MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
     281             :                                                      const ConstantFP &Val) {
     282             :   assert(MRI->getType(Res).isScalar() && "invalid operand type");
     283             : 
     284          54 :   return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
     285             : }
     286             : 
     287          23 : MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
     288             :                                                   MachineBasicBlock &Dest) {
     289             :   assert(MRI->getType(Tst).isScalar() && "invalid operand type");
     290             : 
     291          69 :   return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
     292             : }
     293             : 
     294         536 : 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        1072 :   return buildInstr(TargetOpcode::G_LOAD)
     300         536 :       .addDef(Res)
     301         536 :       .addUse(Addr)
     302        1072 :       .addMemOperand(&MMO);
     303             : }
     304             : 
     305         295 : 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         590 :   return buildInstr(TargetOpcode::G_STORE)
     311         295 :       .addUse(Val)
     312         295 :       .addUse(Addr)
     313         590 :       .addMemOperand(&MMO);
     314             : }
     315             : 
     316           6 : 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          12 :   return buildInstr(TargetOpcode::G_UADDE)
     327           6 :       .addDef(Res)
     328           6 :       .addDef(CarryOut)
     329           6 :       .addUse(Op0)
     330           6 :       .addUse(Op1)
     331          12 :       .addUse(CarryIn);
     332             : }
     333             : 
     334         109 : MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
     335         109 :   validateTruncExt(Res, Op, true);
     336         327 :   return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
     337             : }
     338             : 
     339          33 : MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
     340          33 :   validateTruncExt(Res, Op, true);
     341          99 :   return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
     342             : }
     343             : 
     344          29 : MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
     345          29 :   validateTruncExt(Res, Op, true);
     346          87 :   return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
     347             : }
     348             : 
     349             : MachineInstrBuilder
     350          85 : 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          85 :   unsigned Opcode = TargetOpcode::COPY;
     358          85 :   if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
     359             :     Opcode = ExtOpc;
     360          76 :   else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
     361          48 :     Opcode = TargetOpcode::G_TRUNC;
     362             :   else
     363             :     assert(MRI->getType(Res) == MRI->getType(Op));
     364             : 
     365         255 :   return buildInstr(Opcode).addDef(Res).addUse(Op);
     366             : }
     367             : 
     368           4 : MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
     369             :                                                        unsigned Op) {
     370           4 :   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          77 : MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(unsigned Res,
     379             :                                                          unsigned Op) {
     380          77 :   return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
     381             : }
     382             : 
     383          11 : MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
     384          11 :   LLT SrcTy = MRI->getType(Src);
     385          11 :   LLT DstTy = MRI->getType(Dst);
     386          11 :   if (SrcTy == DstTy)
     387           7 :     return buildCopy(Dst, Src);
     388             : 
     389             :   unsigned Opcode;
     390           3 :   if (SrcTy.isPointer() && DstTy.isScalar())
     391             :     Opcode = TargetOpcode::G_PTRTOINT;
     392           1 :   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          12 :   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          57 :       .addDef(Res)
     419          57 :       .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           9 :   bool MaybeMerge = true;
     440          21 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     441          72 :     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          44 :   for (unsigned i = 0; i < Ops.size(); ++i) {
     456             :     unsigned ResOut =
     457          18 :         i + 1 == Ops.size() ? Res : MRI->createGenericVirtualRegister(ResTy);
     458          54 :     buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
     459          18 :     ResIn = ResOut;
     460             :   }
     461             : }
     462             : 
     463          63 : MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) {
     464         126 :   return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
     465             : }
     466             : 
     467         243 : 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         243 :   if (Ops.size() == 1)
     481           7 :     return buildCast(Res, Ops[0]);
     482             : 
     483         236 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
     484         236 :   MIB.addDef(Res);
     485         853 :   for (unsigned i = 0; i < Ops.size(); ++i)
     486        1851 :     MIB.addUse(Ops[i]);
     487         236 :   return MIB;
     488             : }
     489             : 
     490         289 : 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         289 :   MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
     504         999 :   for (unsigned i = 0; i < Res.size(); ++i)
     505        2130 :     MIB.addDef(Res[i]);
     506         289 :   MIB.addUse(Op);
     507         289 :   return MIB;
     508             : }
     509             : 
     510          90 : 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          90 :   if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
     517           4 :     return buildCast(Res, Op);
     518             :   }
     519             : 
     520         172 :   return buildInstr(TargetOpcode::G_INSERT)
     521          86 :       .addDef(Res)
     522          86 :       .addUse(Src)
     523          86 :       .addUse(Op)
     524         172 :       .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           9 :   MIB.addIntrinsicID(ID);
     536           9 :   return MIB;
     537             : }
     538             : 
     539         209 : MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
     540         209 :   validateTruncExt(Res, Op, false);
     541         627 :   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           3 :   return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
     547             : }
     548             : 
     549          98 : 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         196 :   return buildInstr(TargetOpcode::G_ICMP)
     565          98 :       .addDef(Res)
     566          98 :       .addPredicate(Pred)
     567          98 :       .addUse(Op0)
     568         196 :       .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           7 :       .addDef(Res)
     590           7 :       .addPredicate(Pred)
     591           7 :       .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           6 :       .addDef(Res)
     615           6 :       .addUse(Tst)
     616           6 :       .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          19 :       .addDef(Res)
     637          19 :       .addUse(Val)
     638          19 :       .addUse(Elt)
     639          38 :       .addUse(Idx);
     640             : }
     641             : 
     642          18 : 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          36 :   return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
     656          18 :       .addDef(Res)
     657          18 :       .addUse(Val)
     658          36 :       .addUse(Idx);
     659             : }
     660             : 
     661         381 : void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
     662             :                                         bool IsExtend) {
     663             : #ifndef NDEBUG
     664             :   LLT SrcTy = MRI->getType(Src);
     665             :   LLT DstTy = MRI->getType(Dst);
     666             : 
     667             :   if (DstTy.isVector()) {
     668             :     assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
     669             :     assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
     670             :            "different number of elements in a trunc/ext");
     671             :   } else
     672             :     assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
     673             : 
     674             :   if (IsExtend)
     675             :     assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
     676             :            "invalid narrowing extend");
     677             :   else
     678             :     assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
     679             :            "invalid widening trunc");
     680             : #endif
     681         381 : }

Generated by: LCOV version 1.13