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