LLVM  12.0.0git
InlineAsmLowering.cpp
Go to the documentation of this file.
1 //===-- lib/CodeGen/GlobalISel/InlineAsmLowering.cpp ----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
11 ///
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/CodeGen/Analysis.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 
26 #define DEBUG_TYPE "inline-asm-lowering"
27 
28 using namespace llvm;
29 
30 void InlineAsmLowering::anchor() {}
31 
32 namespace {
33 
34 /// GISelAsmOperandInfo - This contains information for each constraint that we
35 /// are lowering.
36 class GISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
37 public:
38  /// Regs - If this is a register or register class operand, this
39  /// contains the set of assigned registers corresponding to the operand.
41 
42  explicit GISelAsmOperandInfo(const TargetLowering::AsmOperandInfo &Info)
44 };
45 
46 using GISelAsmOperandInfoVector = SmallVector<GISelAsmOperandInfo, 16>;
47 
48 class ExtraFlags {
49  unsigned Flags = 0;
50 
51 public:
52  explicit ExtraFlags(const CallBase &CB) {
53  const InlineAsm *IA = cast<InlineAsm>(CB.getCalledOperand());
54  if (IA->hasSideEffects())
56  if (IA->isAlignStack())
58  if (CB.isConvergent())
60  Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
61  }
62 
63  void update(const TargetLowering::AsmOperandInfo &OpInfo) {
64  // Ideally, we would only check against memory constraints. However, the
65  // meaning of an Other constraint can be target-specific and we can't easily
66  // reason about it. Therefore, be conservative and set MayLoad/MayStore
67  // for Other constraints as well.
70  if (OpInfo.Type == InlineAsm::isInput)
71  Flags |= InlineAsm::Extra_MayLoad;
72  else if (OpInfo.Type == InlineAsm::isOutput)
74  else if (OpInfo.Type == InlineAsm::isClobber)
76  }
77  }
78 
79  unsigned get() const { return Flags; }
80 };
81 
82 } // namespace
83 
84 /// Assign virtual/physical registers for the specified register operand.
86  MachineIRBuilder &MIRBuilder,
87  GISelAsmOperandInfo &OpInfo,
88  GISelAsmOperandInfo &RefOpInfo) {
89 
90  const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
92 
93  // No work to do for memory operations.
94  if (OpInfo.ConstraintType == TargetLowering::C_Memory)
95  return;
96 
97  // If this is a constraint for a single physreg, or a constraint for a
98  // register class, find it.
99  Register AssignedReg;
100  const TargetRegisterClass *RC;
101  std::tie(AssignedReg, RC) = TLI.getRegForInlineAsmConstraint(
102  &TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
103  // RC is unset only on failure. Return immediately.
104  if (!RC)
105  return;
106 
107  // No need to allocate a matching input constraint since the constraint it's
108  // matching to has already been allocated.
109  if (OpInfo.isMatchingInputConstraint())
110  return;
111 
112  // Initialize NumRegs.
113  unsigned NumRegs = 1;
114  if (OpInfo.ConstraintVT != MVT::Other)
115  NumRegs =
116  TLI.getNumRegisters(MF.getFunction().getContext(), OpInfo.ConstraintVT);
117 
118  // If this is a constraint for a specific physical register, but the type of
119  // the operand requires more than one register to be passed, we allocate the
120  // required amount of physical registers, starting from the selected physical
121  // register.
122  // For this, first retrieve a register iterator for the given register class
124  MachineRegisterInfo &RegInfo = MF.getRegInfo();
125 
126  // Advance the iterator to the assigned register (if set)
127  if (AssignedReg) {
128  for (; *I != AssignedReg; ++I)
129  assert(I != RC->end() && "AssignedReg should be a member of provided RC");
130  }
131 
132  // Finally, assign the registers. If the AssignedReg isn't set, create virtual
133  // registers with the provided register class
134  for (; NumRegs; --NumRegs, ++I) {
135  assert(I != RC->end() && "Ran out of registers to allocate!");
136  Register R = AssignedReg ? Register(*I) : RegInfo.createVirtualRegister(RC);
137  OpInfo.Regs.push_back(R);
138  }
139 }
140 
141 /// Return an integer indicating how general CT is.
143  switch (CT) {
147  return 0;
149  return 1;
151  return 2;
153  return 3;
154  }
155  llvm_unreachable("Invalid constraint type");
156 }
157 
159  const TargetLowering *TLI) {
160  assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
161  unsigned BestIdx = 0;
163  int BestGenerality = -1;
164 
165  // Loop over the options, keeping track of the most general one.
166  for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) {
168  TLI->getConstraintType(OpInfo.Codes[i]);
169 
170  // Indirect 'other' or 'immediate' constraints are not allowed.
171  if (OpInfo.isIndirect && !(CType == TargetLowering::C_Memory ||
172  CType == TargetLowering::C_Register ||
174  continue;
175 
176  // If this is an 'other' or 'immediate' constraint, see if the operand is
177  // valid for it. For example, on X86 we might have an 'rI' constraint. If
178  // the operand is an integer in the range [0..31] we want to use I (saving a
179  // load of a register), otherwise we must use 'r'.
180  if (CType == TargetLowering::C_Other ||
181  CType == TargetLowering::C_Immediate) {
182  assert(OpInfo.Codes[i].size() == 1 &&
183  "Unhandled multi-letter 'other' constraint");
184  // FIXME: prefer immediate constraints if the target allows it
185  }
186 
187  // Things with matching constraints can only be registers, per gcc
188  // documentation. This mainly affects "g" constraints.
189  if (CType == TargetLowering::C_Memory && OpInfo.hasMatchingInput())
190  continue;
191 
192  // This constraint letter is more general than the previous one, use it.
193  int Generality = getConstraintGenerality(CType);
194  if (Generality > BestGenerality) {
195  BestType = CType;
196  BestIdx = i;
197  BestGenerality = Generality;
198  }
199  }
200 
201  OpInfo.ConstraintCode = OpInfo.Codes[BestIdx];
202  OpInfo.ConstraintType = BestType;
203 }
204 
205 static void computeConstraintToUse(const TargetLowering *TLI,
207  assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
208 
209  // Single-letter constraints ('r') are very common.
210  if (OpInfo.Codes.size() == 1) {
211  OpInfo.ConstraintCode = OpInfo.Codes[0];
212  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
213  } else {
214  chooseConstraint(OpInfo, TLI);
215  }
216 
217  // 'X' matches anything.
218  if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
219  // Labels and constants are handled elsewhere ('X' is the only thing
220  // that matches labels). For Functions, the type here is the type of
221  // the result, which is not what we want to look at; leave them alone.
222  Value *Val = OpInfo.CallOperandVal;
223  if (isa<BasicBlock>(Val) || isa<ConstantInt>(Val) || isa<Function>(Val))
224  return;
225 
226  // Otherwise, try to resolve it to something we know about by looking at
227  // the actual operand type.
228  if (const char *Repl = TLI->LowerXConstraint(OpInfo.ConstraintVT)) {
229  OpInfo.ConstraintCode = Repl;
230  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
231  }
232  }
233 }
234 
235 static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx) {
236  unsigned Flag = I.getOperand(OpIdx).getImm();
238 }
239 
240 static bool buildAnyextOrCopy(Register Dst, Register Src,
241  MachineIRBuilder &MIRBuilder) {
242  const TargetRegisterInfo *TRI =
243  MIRBuilder.getMF().getSubtarget().getRegisterInfo();
244  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
245 
246  auto SrcTy = MRI->getType(Src);
247  if (!SrcTy.isValid()) {
248  LLVM_DEBUG(dbgs() << "Source type for copy is not valid\n");
249  return false;
250  }
251  unsigned SrcSize = TRI->getRegSizeInBits(Src, *MRI);
252  unsigned DstSize = TRI->getRegSizeInBits(Dst, *MRI);
253 
254  if (DstSize < SrcSize) {
255  LLVM_DEBUG(dbgs() << "Input can't fit in destination reg class\n");
256  return false;
257  }
258 
259  // Attempt to anyext small scalar sources.
260  if (DstSize > SrcSize) {
261  if (!SrcTy.isScalar()) {
262  LLVM_DEBUG(dbgs() << "Can't extend non-scalar input to size of"
263  "destination register class\n");
264  return false;
265  }
266  Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
267  }
268 
269  MIRBuilder.buildCopy(Dst, Src);
270  return true;
271 }
272 
274  MachineIRBuilder &MIRBuilder, const CallBase &Call,
275  std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
276  const {
277  const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
278 
279  /// ConstraintOperands - Information about all of the constraints.
280  GISelAsmOperandInfoVector ConstraintOperands;
281 
282  MachineFunction &MF = MIRBuilder.getMF();
283  const Function &F = MF.getFunction();
284  const DataLayout &DL = F.getParent()->getDataLayout();
286 
287  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
288 
289  TargetLowering::AsmOperandInfoVector TargetConstraints =
290  TLI->ParseConstraints(DL, TRI, Call);
291 
292  ExtraFlags ExtraInfo(Call);
293  unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
294  unsigned ResNo = 0; // ResNo - The result number of the next output.
295  for (auto &T : TargetConstraints) {
296  ConstraintOperands.push_back(GISelAsmOperandInfo(T));
297  GISelAsmOperandInfo &OpInfo = ConstraintOperands.back();
298 
299  // Compute the value type for each operand.
300  if (OpInfo.Type == InlineAsm::isInput ||
301  (OpInfo.Type == InlineAsm::isOutput && OpInfo.isIndirect)) {
302 
303  OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo++));
304 
305  if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
306  LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
307  return false;
308  }
309 
310  Type *OpTy = OpInfo.CallOperandVal->getType();
311 
312  // If this is an indirect operand, the operand is a pointer to the
313  // accessed type.
314  if (OpInfo.isIndirect) {
315  PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
316  if (!PtrTy)
317  report_fatal_error("Indirect operand for inline asm not a pointer!");
318  OpTy = PtrTy->getElementType();
319  }
320 
321  // FIXME: Support aggregate input operands
322  if (!OpTy->isSingleValueType()) {
323  LLVM_DEBUG(
324  dbgs() << "Aggregate input operands are not supported yet\n");
325  return false;
326  }
327 
328  OpInfo.ConstraintVT = TLI->getValueType(DL, OpTy, true).getSimpleVT();
329 
330  } else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
331  assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
332  if (StructType *STy = dyn_cast<StructType>(Call.getType())) {
333  OpInfo.ConstraintVT =
334  TLI->getSimpleValueType(DL, STy->getElementType(ResNo));
335  } else {
336  assert(ResNo == 0 && "Asm only has one result!");
337  OpInfo.ConstraintVT = TLI->getSimpleValueType(DL, Call.getType());
338  }
339  ++ResNo;
340  } else {
341  OpInfo.ConstraintVT = MVT::Other;
342  }
343 
344  // Compute the constraint code and ConstraintType to use.
345  computeConstraintToUse(TLI, OpInfo);
346 
347  // The selected constraint type might expose new sideeffects
348  ExtraInfo.update(OpInfo);
349  }
350 
351  // At this point, all operand types are decided.
352  // Create the MachineInstr, but don't insert it yet since input
353  // operands still need to insert instructions before this one
354  auto Inst = MIRBuilder.buildInstrNoInsert(TargetOpcode::INLINEASM)
355  .addExternalSymbol(IA->getAsmString().c_str())
356  .addImm(ExtraInfo.get());
357 
358  // Starting from this operand: flag followed by register(s) will be added as
359  // operands to Inst for each constraint. Used for matching input constraints.
360  unsigned StartIdx = Inst->getNumOperands();
361 
362  // Collects the output operands for later processing
363  GISelAsmOperandInfoVector OutputOperands;
364 
365  for (auto &OpInfo : ConstraintOperands) {
366  GISelAsmOperandInfo &RefOpInfo =
367  OpInfo.isMatchingInputConstraint()
368  ? ConstraintOperands[OpInfo.getMatchedOperand()]
369  : OpInfo;
370 
371  // Assign registers for register operands
372  getRegistersForValue(MF, MIRBuilder, OpInfo, RefOpInfo);
373 
374  switch (OpInfo.Type) {
375  case InlineAsm::isOutput:
376  if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
377  unsigned ConstraintID =
378  TLI->getInlineAsmMemConstraint(OpInfo.ConstraintCode);
379  assert(ConstraintID != InlineAsm::Constraint_Unknown &&
380  "Failed to convert memory constraint code to constraint id.");
381 
382  // Add information to the INLINEASM instruction to know about this
383  // output.
384  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
385  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
386  Inst.addImm(OpFlags);
387  ArrayRef<Register> SourceRegs =
388  GetOrCreateVRegs(*OpInfo.CallOperandVal);
389  assert(
390  SourceRegs.size() == 1 &&
391  "Expected the memory output to fit into a single virtual register");
392  Inst.addReg(SourceRegs[0]);
393  } else {
394  // Otherwise, this outputs to a register (directly for C_Register /
395  // C_RegisterClass. Find a register that we can use.
396  assert(OpInfo.ConstraintType == TargetLowering::C_Register ||
397  OpInfo.ConstraintType == TargetLowering::C_RegisterClass);
398 
399  if (OpInfo.Regs.empty()) {
400  LLVM_DEBUG(dbgs()
401  << "Couldn't allocate output register for constraint\n");
402  return false;
403  }
404 
405  // Add information to the INLINEASM instruction to know that this
406  // register is set.
407  unsigned Flag = InlineAsm::getFlagWord(
408  OpInfo.isEarlyClobber ? InlineAsm::Kind_RegDefEarlyClobber
410  OpInfo.Regs.size());
411  if (OpInfo.Regs.front().isVirtual()) {
412  // Put the register class of the virtual registers in the flag word.
413  // That way, later passes can recompute register class constraints for
414  // inline assembly as well as normal instructions. Don't do this for
415  // tied operands that can use the regclass information from the def.
416  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
417  Flag = InlineAsm::getFlagWordForRegClass(Flag, RC->getID());
418  }
419 
420  Inst.addImm(Flag);
421 
422  for (Register Reg : OpInfo.Regs) {
423  Inst.addReg(Reg,
425  (OpInfo.isEarlyClobber ? RegState::EarlyClobber : 0));
426  }
427 
428  // Remember this output operand for later processing
429  OutputOperands.push_back(OpInfo);
430  }
431 
432  break;
433  case InlineAsm::isInput: {
434  if (OpInfo.isMatchingInputConstraint()) {
435  unsigned DefIdx = OpInfo.getMatchedOperand();
436  // Find operand with register def that corresponds to DefIdx.
437  unsigned InstFlagIdx = StartIdx;
438  for (unsigned i = 0; i < DefIdx; ++i)
439  InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1;
440  assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag");
441 
442  unsigned MatchedOperandFlag = Inst->getOperand(InstFlagIdx).getImm();
443  if (InlineAsm::isMemKind(MatchedOperandFlag)) {
444  LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
445  "supported. This should be target specific.\n");
446  return false;
447  }
448  if (!InlineAsm::isRegDefKind(MatchedOperandFlag) &&
449  !InlineAsm::isRegDefEarlyClobberKind(MatchedOperandFlag)) {
450  LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
451  return false;
452  }
453 
454  // We want to tie input to register in next operand.
455  unsigned DefRegIdx = InstFlagIdx + 1;
456  Register Def = Inst->getOperand(DefRegIdx).getReg();
457 
458  // Copy input to new vreg with same reg class as Def
459  const TargetRegisterClass *RC = MRI->getRegClass(Def);
460  ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
461  assert(SrcRegs.size() == 1 && "Single register is expected here");
462  Register Tmp = MRI->createVirtualRegister(RC);
463  if (!buildAnyextOrCopy(Tmp, SrcRegs[0], MIRBuilder))
464  return false;
465 
466  // Add Flag and input register operand (Tmp) to Inst. Tie Tmp to Def.
467  unsigned UseFlag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, 1);
468  unsigned Flag = InlineAsm::getFlagWordForMatchingOp(UseFlag, DefIdx);
469  Inst.addImm(Flag);
470  Inst.addReg(Tmp);
471  Inst->tieOperands(DefRegIdx, Inst->getNumOperands() - 1);
472  break;
473  }
474 
475  if (OpInfo.ConstraintType == TargetLowering::C_Other &&
476  OpInfo.isIndirect) {
477  LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
478  "not supported yet\n");
479  return false;
480  }
481 
482  if (OpInfo.ConstraintType == TargetLowering::C_Immediate ||
483  OpInfo.ConstraintType == TargetLowering::C_Other) {
484 
485  std::vector<MachineOperand> Ops;
486  if (!lowerAsmOperandForConstraint(OpInfo.CallOperandVal,
487  OpInfo.ConstraintCode, Ops,
488  MIRBuilder)) {
489  LLVM_DEBUG(dbgs() << "Don't support constraint: "
490  << OpInfo.ConstraintCode << " yet\n");
491  return false;
492  }
493 
494  assert(Ops.size() > 0 &&
495  "Expected constraint to be lowered to at least one operand");
496 
497  // Add information to the INLINEASM node to know about this input.
498  unsigned OpFlags =
500  Inst.addImm(OpFlags);
501  Inst.add(Ops);
502  break;
503  }
504 
505  if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
506 
507  if (!OpInfo.isIndirect) {
508  LLVM_DEBUG(dbgs()
509  << "Cannot indirectify memory input operands yet\n");
510  return false;
511  }
512 
513  assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
514 
515  unsigned ConstraintID =
516  TLI->getInlineAsmMemConstraint(OpInfo.ConstraintCode);
517  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
518  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
519  Inst.addImm(OpFlags);
520  ArrayRef<Register> SourceRegs =
521  GetOrCreateVRegs(*OpInfo.CallOperandVal);
522  assert(
523  SourceRegs.size() == 1 &&
524  "Expected the memory input to fit into a single virtual register");
525  Inst.addReg(SourceRegs[0]);
526  break;
527  }
528 
529  assert((OpInfo.ConstraintType == TargetLowering::C_RegisterClass ||
530  OpInfo.ConstraintType == TargetLowering::C_Register) &&
531  "Unknown constraint type!");
532 
533  if (OpInfo.isIndirect) {
534  LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
535  "for constraint '"
536  << OpInfo.ConstraintCode << "'\n");
537  return false;
538  }
539 
540  // Copy the input into the appropriate registers.
541  if (OpInfo.Regs.empty()) {
542  LLVM_DEBUG(
543  dbgs()
544  << "Couldn't allocate input register for register constraint\n");
545  return false;
546  }
547 
548  unsigned NumRegs = OpInfo.Regs.size();
549  ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
550  assert(NumRegs == SourceRegs.size() &&
551  "Expected the number of input registers to match the number of "
552  "source registers");
553 
554  if (NumRegs > 1) {
555  LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
556  "not supported yet\n");
557  return false;
558  }
559 
561  Inst.addImm(Flag);
562  if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
563  return false;
564  Inst.addReg(OpInfo.Regs[0]);
565  break;
566  }
567 
568  case InlineAsm::isClobber: {
569 
570  unsigned NumRegs = OpInfo.Regs.size();
571  if (NumRegs > 0) {
572  unsigned Flag =
574  Inst.addImm(Flag);
575 
576  for (Register Reg : OpInfo.Regs) {
577  Inst.addReg(Reg, RegState::Define | RegState::EarlyClobber |
578  getImplRegState(Reg.isPhysical()));
579  }
580  }
581  break;
582  }
583  }
584  }
585 
586  if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
587  Inst.addMetadata(SrcLoc);
588 
589  // All inputs are handled, insert the instruction now
590  MIRBuilder.insertInstr(Inst);
591 
592  // Finally, copy the output operands into the output registers
593  ArrayRef<Register> ResRegs = GetOrCreateVRegs(Call);
594  if (ResRegs.size() != OutputOperands.size()) {
595  LLVM_DEBUG(dbgs() << "Expected the number of output registers to match the "
596  "number of destination registers\n");
597  return false;
598  }
599  for (unsigned int i = 0, e = ResRegs.size(); i < e; i++) {
600  GISelAsmOperandInfo &OpInfo = OutputOperands[i];
601 
602  if (OpInfo.Regs.empty())
603  continue;
604 
605  switch (OpInfo.ConstraintType) {
608  if (OpInfo.Regs.size() > 1) {
609  LLVM_DEBUG(dbgs() << "Output operands with multiple defining "
610  "registers are not supported yet\n");
611  return false;
612  }
613 
614  Register SrcReg = OpInfo.Regs[0];
615  unsigned SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
616  if (MRI->getType(ResRegs[i]).getSizeInBits() < SrcSize) {
617  // First copy the non-typed virtual register into a generic virtual
618  // register
619  Register Tmp1Reg =
621  MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
622  // Need to truncate the result of the register
623  MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
624  } else {
625  MIRBuilder.buildCopy(ResRegs[i], SrcReg);
626  }
627  break;
628  }
631  LLVM_DEBUG(
632  dbgs() << "Cannot lower target specific output constraints yet\n");
633  return false;
635  break; // Already handled.
637  LLVM_DEBUG(dbgs() << "Unexpected unknown constraint\n");
638  return false;
639  }
640  }
641 
642  return true;
643 }
644 
646  Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
647  MachineIRBuilder &MIRBuilder) const {
648  if (Constraint.size() > 1)
649  return false;
650 
651  char ConstraintLetter = Constraint[0];
652  switch (ConstraintLetter) {
653  default:
654  return false;
655  case 'i': // Simple Integer or Relocatable Constant
656  if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
657  assert(CI->getBitWidth() <= 64 &&
658  "expected immediate to fit into 64-bits");
659  // Boolean constants should be zero-extended, others are sign-extended
660  bool IsBool = CI->getBitWidth() == 1;
661  int64_t ExtVal = IsBool ? CI->getZExtValue() : CI->getSExtValue();
662  Ops.push_back(MachineOperand::CreateImm(ExtVal));
663  return true;
664  }
665  return false;
666  }
667 }
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
iterator begin() const
begin/end - Return all of the registers in this class.
Register getReg(unsigned Idx) const
Get the register for the operand index.
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1748
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Definition: InlineAsm.h:270
unsigned Reg
static bool buildAnyextOrCopy(Register Dst, Register Src, MachineIRBuilder &MIRBuilder)
virtual const TargetLowering * getTargetLowering() const
const std::string & getAsmString() const
Definition: InlineAsm.h:81
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
unsigned const TargetRegisterInfo * TRI
Metadata node.
Definition: Metadata.h:870
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1100
F(f)
virtual bool lowerAsmOperandForConstraint(Value *Val, StringRef Constraint, std::vector< MachineOperand > &Ops, MachineIRBuilder &MIRBuilder) const
Lower the specified operand into the Ops vector.
Value * CallOperandVal
If this is the result output operand or a clobber, this is null, otherwise it is the incoming operand...
bool hasMatchingInput() const
hasMatchingInput - Return true if this is an output constraint that has a matching input constraint...
Definition: InlineAsm.h:135
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number...
Definition: InlineAsm.h:149
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool hasSideEffects() const
Definition: InlineAsm.h:67
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1259
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
Definition: InlineAsm.h:301
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:397
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:459
static void chooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, const TargetLowering *TLI)
Class to represent struct types.
Definition: DerivedTypes.h:218
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT)
Return an integer indicating how general CT is.
static bool isRegDefEarlyClobberKind(unsigned Flag)
Definition: InlineAsm.h:279
unsigned getID() const
Return the register class ID number.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:871
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:244
Value * getCalledOperand() const
Definition: InstrTypes.h:1307
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don&#39;t insert <empty> = Opcode <empty>.
This contains information for each constraint that we are lowering.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
MachineFunction & getMF()
Getter for the function we currently build.
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:98
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:279
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber.
Definition: InlineAsm.h:121
static bool isRegDefKind(unsigned Flag)
Definition: InlineAsm.h:276
Analysis containing CSE Info
Definition: CSEInfo.cpp:25
Class to represent pointers.
Definition: DerivedTypes.h:662
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:138
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:138
MachineRegisterInfo * getMRI()
Getter for MRI.
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual const char * LowerXConstraint(EVT ConstraintVT) const
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:145
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:156
Helper class to build MachineInstr.
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
Definition: InlineAsm.h:337
constexpr double e
Definition: MathExtras.h:58
static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint)
Augment an existing flag word returned by getFlagWord with the constraint code for a memory constrain...
Definition: InlineAsm.h:313
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:252
static bool isMemKind(unsigned Flag)
Definition: InlineAsm.h:278
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
bool isAlignStack() const
Definition: InlineAsm.h:68
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::string ConstraintCode
This contains the actual string for the code, like "m".
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This is the shared class of boolean and integer constants.
Definition: Constants.h:77
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
Module.h This file contains the declarations for the Module class.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Promote Memory to Register
Definition: Mem2Reg.cpp:110
int64_t getImm() const
This file declares the MachineIRBuilder class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:62
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:59
unsigned getImplRegState(bool B)
unsigned getNumRegisters(LLVMContext &Context, EVT VT) const
Return the number of registers that this ValueType will eventually require.
AsmDialect getDialect() const
Definition: InlineAsm.h:69
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition: Type.h:253
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
LLVM Value Representation.
Definition: Value.h:74
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
MVT ConstraintVT
The ValueType for the operand value.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
Type * getElementType() const
Definition: DerivedTypes.h:681
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
Definition: InlineAsm.h:289
This file describes how to lower LLVM code to machine code.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL