LLVM  14.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)
43  : 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.hasArg()) {
301  OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo));
302 
303  if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
304  LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
305  return false;
306  }
307 
308  Type *OpTy = OpInfo.CallOperandVal->getType();
309 
310  // If this is an indirect operand, the operand is a pointer to the
311  // accessed type.
312  if (OpInfo.isIndirect) {
313  OpTy = Call.getAttributes().getParamElementType(ArgNo);
314  assert(OpTy && "Indirect operand must have elementtype attribute");
315  }
316 
317  // FIXME: Support aggregate input operands
318  if (!OpTy->isSingleValueType()) {
319  LLVM_DEBUG(
320  dbgs() << "Aggregate input operands are not supported yet\n");
321  return false;
322  }
323 
324  OpInfo.ConstraintVT =
325  TLI->getAsmOperandValueType(DL, OpTy, true).getSimpleVT();
326  ++ArgNo;
327  } else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
328  assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
329  if (StructType *STy = dyn_cast<StructType>(Call.getType())) {
330  OpInfo.ConstraintVT =
331  TLI->getSimpleValueType(DL, STy->getElementType(ResNo));
332  } else {
333  assert(ResNo == 0 && "Asm only has one result!");
334  OpInfo.ConstraintVT =
335  TLI->getAsmOperandValueType(DL, Call.getType()).getSimpleVT();
336  }
337  ++ResNo;
338  } else {
339  OpInfo.ConstraintVT = MVT::Other;
340  }
341 
342  if (OpInfo.ConstraintVT == MVT::i64x8)
343  return false;
344 
345  // Compute the constraint code and ConstraintType to use.
346  computeConstraintToUse(TLI, OpInfo);
347 
348  // The selected constraint type might expose new sideeffects
349  ExtraInfo.update(OpInfo);
350  }
351 
352  // At this point, all operand types are decided.
353  // Create the MachineInstr, but don't insert it yet since input
354  // operands still need to insert instructions before this one
355  auto Inst = MIRBuilder.buildInstrNoInsert(TargetOpcode::INLINEASM)
356  .addExternalSymbol(IA->getAsmString().c_str())
357  .addImm(ExtraInfo.get());
358 
359  // Starting from this operand: flag followed by register(s) will be added as
360  // operands to Inst for each constraint. Used for matching input constraints.
361  unsigned StartIdx = Inst->getNumOperands();
362 
363  // Collects the output operands for later processing
364  GISelAsmOperandInfoVector OutputOperands;
365 
366  for (auto &OpInfo : ConstraintOperands) {
367  GISelAsmOperandInfo &RefOpInfo =
369  ? ConstraintOperands[OpInfo.getMatchedOperand()]
370  : OpInfo;
371 
372  // Assign registers for register operands
373  getRegistersForValue(MF, MIRBuilder, OpInfo, RefOpInfo);
374 
375  switch (OpInfo.Type) {
376  case InlineAsm::isOutput:
378  unsigned ConstraintID =
380  assert(ConstraintID != InlineAsm::Constraint_Unknown &&
381  "Failed to convert memory constraint code to constraint id.");
382 
383  // Add information to the INLINEASM instruction to know about this
384  // output.
385  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
386  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
387  Inst.addImm(OpFlags);
388  ArrayRef<Register> SourceRegs =
389  GetOrCreateVRegs(*OpInfo.CallOperandVal);
390  assert(
391  SourceRegs.size() == 1 &&
392  "Expected the memory output to fit into a single virtual register");
393  Inst.addReg(SourceRegs[0]);
394  } else {
395  // Otherwise, this outputs to a register (directly for C_Register /
396  // C_RegisterClass. Find a register that we can use.
399 
400  if (OpInfo.Regs.empty()) {
401  LLVM_DEBUG(dbgs()
402  << "Couldn't allocate output register for constraint\n");
403  return false;
404  }
405 
406  // Add information to the INLINEASM instruction to know that this
407  // register is set.
408  unsigned Flag = InlineAsm::getFlagWord(
411  OpInfo.Regs.size());
412  if (OpInfo.Regs.front().isVirtual()) {
413  // Put the register class of the virtual registers in the flag word.
414  // That way, later passes can recompute register class constraints for
415  // inline assembly as well as normal instructions. Don't do this for
416  // tied operands that can use the regclass information from the def.
417  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
419  }
420 
421  Inst.addImm(Flag);
422 
423  for (Register Reg : OpInfo.Regs) {
424  Inst.addReg(Reg,
425  RegState::Define | getImplRegState(Reg.isPhysical()) |
426  (OpInfo.isEarlyClobber ? RegState::EarlyClobber : 0));
427  }
428 
429  // Remember this output operand for later processing
430  OutputOperands.push_back(OpInfo);
431  }
432 
433  break;
434  case InlineAsm::isInput: {
435  if (OpInfo.isMatchingInputConstraint()) {
436  unsigned DefIdx = OpInfo.getMatchedOperand();
437  // Find operand with register def that corresponds to DefIdx.
438  unsigned InstFlagIdx = StartIdx;
439  for (unsigned i = 0; i < DefIdx; ++i)
440  InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1;
441  assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag");
442 
443  unsigned MatchedOperandFlag = Inst->getOperand(InstFlagIdx).getImm();
444  if (InlineAsm::isMemKind(MatchedOperandFlag)) {
445  LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
446  "supported. This should be target specific.\n");
447  return false;
448  }
449  if (!InlineAsm::isRegDefKind(MatchedOperandFlag) &&
450  !InlineAsm::isRegDefEarlyClobberKind(MatchedOperandFlag)) {
451  LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
452  return false;
453  }
454 
455  // We want to tie input to register in next operand.
456  unsigned DefRegIdx = InstFlagIdx + 1;
457  Register Def = Inst->getOperand(DefRegIdx).getReg();
458 
459  ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
460  assert(SrcRegs.size() == 1 && "Single register is expected here");
461 
462  // When Def is physreg: use given input.
463  Register In = SrcRegs[0];
464  // When Def is vreg: copy input to new vreg with same reg class as Def.
465  if (Def.isVirtual()) {
467  if (!buildAnyextOrCopy(In, SrcRegs[0], MIRBuilder))
468  return false;
469  }
470 
471  // Add Flag and input register operand (In) to Inst. Tie In to Def.
472  unsigned UseFlag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, 1);
473  unsigned Flag = InlineAsm::getFlagWordForMatchingOp(UseFlag, DefIdx);
474  Inst.addImm(Flag);
475  Inst.addReg(In);
476  Inst->tieOperands(DefRegIdx, Inst->getNumOperands() - 1);
477  break;
478  }
479 
480  if (OpInfo.ConstraintType == TargetLowering::C_Other &&
481  OpInfo.isIndirect) {
482  LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
483  "not supported yet\n");
484  return false;
485  }
486 
489 
490  std::vector<MachineOperand> Ops;
492  OpInfo.ConstraintCode, Ops,
493  MIRBuilder)) {
494  LLVM_DEBUG(dbgs() << "Don't support constraint: "
495  << OpInfo.ConstraintCode << " yet\n");
496  return false;
497  }
498 
499  assert(Ops.size() > 0 &&
500  "Expected constraint to be lowered to at least one operand");
501 
502  // Add information to the INLINEASM node to know about this input.
503  unsigned OpFlags =
505  Inst.addImm(OpFlags);
506  Inst.add(Ops);
507  break;
508  }
509 
511 
512  if (!OpInfo.isIndirect) {
513  LLVM_DEBUG(dbgs()
514  << "Cannot indirectify memory input operands yet\n");
515  return false;
516  }
517 
518  assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
519 
520  unsigned ConstraintID =
522  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
523  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
524  Inst.addImm(OpFlags);
525  ArrayRef<Register> SourceRegs =
526  GetOrCreateVRegs(*OpInfo.CallOperandVal);
527  assert(
528  SourceRegs.size() == 1 &&
529  "Expected the memory input to fit into a single virtual register");
530  Inst.addReg(SourceRegs[0]);
531  break;
532  }
533 
536  "Unknown constraint type!");
537 
538  if (OpInfo.isIndirect) {
539  LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
540  "for constraint '"
541  << OpInfo.ConstraintCode << "'\n");
542  return false;
543  }
544 
545  // Copy the input into the appropriate registers.
546  if (OpInfo.Regs.empty()) {
547  LLVM_DEBUG(
548  dbgs()
549  << "Couldn't allocate input register for register constraint\n");
550  return false;
551  }
552 
553  unsigned NumRegs = OpInfo.Regs.size();
554  ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
555  assert(NumRegs == SourceRegs.size() &&
556  "Expected the number of input registers to match the number of "
557  "source registers");
558 
559  if (NumRegs > 1) {
560  LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
561  "not supported yet\n");
562  return false;
563  }
564 
566  if (OpInfo.Regs.front().isVirtual()) {
567  // Put the register class of the virtual registers in the flag word.
568  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
570  }
571  Inst.addImm(Flag);
572  if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
573  return false;
574  Inst.addReg(OpInfo.Regs[0]);
575  break;
576  }
577 
578  case InlineAsm::isClobber: {
579 
580  unsigned NumRegs = OpInfo.Regs.size();
581  if (NumRegs > 0) {
582  unsigned Flag =
584  Inst.addImm(Flag);
585 
586  for (Register Reg : OpInfo.Regs) {
588  getImplRegState(Reg.isPhysical()));
589  }
590  }
591  break;
592  }
593  }
594  }
595 
596  if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
597  Inst.addMetadata(SrcLoc);
598 
599  // All inputs are handled, insert the instruction now
600  MIRBuilder.insertInstr(Inst);
601 
602  // Finally, copy the output operands into the output registers
603  ArrayRef<Register> ResRegs = GetOrCreateVRegs(Call);
604  if (ResRegs.size() != OutputOperands.size()) {
605  LLVM_DEBUG(dbgs() << "Expected the number of output registers to match the "
606  "number of destination registers\n");
607  return false;
608  }
609  for (unsigned int i = 0, e = ResRegs.size(); i < e; i++) {
610  GISelAsmOperandInfo &OpInfo = OutputOperands[i];
611 
612  if (OpInfo.Regs.empty())
613  continue;
614 
615  switch (OpInfo.ConstraintType) {
618  if (OpInfo.Regs.size() > 1) {
619  LLVM_DEBUG(dbgs() << "Output operands with multiple defining "
620  "registers are not supported yet\n");
621  return false;
622  }
623 
624  Register SrcReg = OpInfo.Regs[0];
625  unsigned SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
626  LLT ResTy = MRI->getType(ResRegs[i]);
627  if (ResTy.isScalar() && ResTy.getSizeInBits() < SrcSize) {
628  // First copy the non-typed virtual register into a generic virtual
629  // register
630  Register Tmp1Reg =
632  MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
633  // Need to truncate the result of the register
634  MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
635  } else if (ResTy.getSizeInBits() == SrcSize) {
636  MIRBuilder.buildCopy(ResRegs[i], SrcReg);
637  } else {
638  LLVM_DEBUG(dbgs() << "Unhandled output operand with "
639  "mismatched register size\n");
640  return false;
641  }
642 
643  break;
644  }
647  LLVM_DEBUG(
648  dbgs() << "Cannot lower target specific output constraints yet\n");
649  return false;
651  break; // Already handled.
653  LLVM_DEBUG(dbgs() << "Unexpected unknown constraint\n");
654  return false;
655  }
656  }
657 
658  return true;
659 }
660 
662  Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
663  MachineIRBuilder &MIRBuilder) const {
664  if (Constraint.size() > 1)
665  return false;
666 
667  char ConstraintLetter = Constraint[0];
668  switch (ConstraintLetter) {
669  default:
670  return false;
671  case 'i': // Simple Integer or Relocatable Constant
672  case 'n': // immediate integer with a known value.
673  if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
674  assert(CI->getBitWidth() <= 64 &&
675  "expected immediate to fit into 64-bits");
676  // Boolean constants should be zero-extended, others are sign-extended
677  bool IsBool = CI->getBitWidth() == 1;
678  int64_t ExtVal = IsBool ? CI->getZExtValue() : CI->getSExtValue();
679  Ops.push_back(MachineOperand::CreateImm(ExtVal));
680  return true;
681  }
682  return false;
683  }
684 }
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:71
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:22
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:158
llvm::TargetLowering::ConstraintType
ConstraintType
Definition: TargetLowering.h:4263
llvm::InlineAsm::getAsmString
const std::string & getAsmString() const
Definition: InlineAsm.h:83
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
T
llvm::Function
Definition: Function.h:62
getRegistersForValue
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
Definition: InlineAsmLowering.cpp:85
llvm::InlineAsm::Extra_MayStore
@ Extra_MayStore
Definition: InlineAsm.h:232
llvm::InlineAsm::isAlignStack
bool isAlignStack() const
Definition: InlineAsm.h:69
llvm::InlineAsm::ConstraintInfo::isIndirect
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:147
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1176
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:280
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:273
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::TargetLowering::C_Memory
@ C_Memory
Definition: TargetLowering.h:4266
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:40
chooseConstraint
static void chooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, const TargetLowering *TLI)
Definition: InlineAsmLowering.cpp:158
MachineIRBuilder.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1564
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::InlineAsm::Extra_IsAlignStack
@ Extra_IsAlignStack
Definition: InlineAsm.h:229
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:984
llvm::InlineAsm::Extra_HasSideEffects
@ Extra_HasSideEffects
Definition: InlineAsm.h:228
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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:248
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:651
InlineAsmLowering.h
llvm::TargetLowering::AsmOperandInfo::ConstraintType
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
Definition: TargetLowering.h:4297
llvm::MachineOperand::CreateImm
static MachineOperand CreateImm(int64_t Val)
Definition: MachineOperand.h:773
llvm::InlineAsm::Kind_Mem
@ Kind_Mem
Definition: InlineAsm.h:243
llvm::InlineAsm::Kind_RegDef
@ Kind_RegDef
Definition: InlineAsm.h:239
llvm::InlineAsm::hasSideEffects
bool hasSideEffects() const
Definition: InlineAsm.h:68
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3277
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:4302
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
Utils.h
llvm::InlineAsm::isInput
@ isInput
Definition: InlineAsm.h:94
llvm::CallBase::isConvergent
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1882
llvm::InlineAsm::isRegDefKind
static bool isRegDefKind(unsigned Flag)
Definition: InlineAsm.h:283
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:146
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:262
llvm::TargetLowering::C_Register
@ C_Register
Definition: TargetLowering.h:4264
llvm::TargetLowering::C_Immediate
@ C_Immediate
Definition: TargetLowering.h:4267
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::InlineAsm::getDialect
AsmDialect getDialect() const
Definition: InlineAsm.h:70
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:4269
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:285
getConstraintGenerality
static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT)
Return an integer indicating how general CT is.
Definition: InlineAsmLowering.cpp:142
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::InlineAsm::Kind_Imm
@ Kind_Imm
Definition: InlineAsm.h:242
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:641
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::TargetLowering::C_Other
@ C_Other
Definition: TargetLowering.h:4268
llvm::MVT::i64x8
@ i64x8
Definition: MachineValueType.h:273
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:212
llvm::InlineAsm::isRegDefEarlyClobberKind
static bool isRegDefEarlyClobberKind(unsigned Flag)
Definition: InlineAsm.h:286
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
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:4756
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:127
Analysis.h
llvm::TargetLowering::AsmOperandInfo
This contains information for each constraint that we are lowering.
Definition: TargetLowering.h:4289
llvm::InlineAsm::Kind_RegUse
@ Kind_RegUse
Definition: InlineAsm.h:238
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:151
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
llvm::InlineAsm::Extra_AsmDialect
@ Extra_AsmDialect
Definition: InlineAsm.h:230
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::InlineAsm::ConstraintInfo::Type
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber.
Definition: InlineAsm.h:123
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:188
llvm::MDNode
Metadata node.
Definition: Metadata.h:906
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:4293
llvm::MachineFunction
Definition: MachineFunction.h:241
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:308
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:1479
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
DataLayout.h
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:58
llvm::MachineIRBuilder::insertInstr
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Definition: MachineIRBuilder.cpp:45
llvm::InlineAsm::getFlagWord
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Definition: InlineAsm.h:277
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::MachineIRBuilder::buildCopy
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
Definition: MachineIRBuilder.cpp:280
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
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:4745
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:4694
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:444
llvm::TargetLowering::C_RegisterClass
@ C_RegisterClass
Definition: TargetLowering.h:4265
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::InlineAsm::Extra_IsConvergent
@ Extra_IsConvergent
Definition: InlineAsm.h:233
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:320
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:296
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::InlineAsm::Kind_Clobber
@ Kind_Clobber
Definition: InlineAsm.h:241
computeConstraintToUse
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
Definition: InlineAsmLowering.cpp:205
llvm::MachineIRBuilder::buildTrunc
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Definition: MachineIRBuilder.cpp:765
llvm::TargetRegisterClass::begin
iterator begin() const
begin/end - Return all of the registers in this class.
Definition: TargetRegisterInfo.h:75
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:607
llvm::TargetRegisterInfo::getRegSizeInBits
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
Definition: TargetRegisterInfo.h:276
uint16_t
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::InlineAsm::isClobber
@ isClobber
Definition: InlineAsm.h:96
llvm::InlineAsm::Kind_RegDefEarlyClobber
@ Kind_RegDefEarlyClobber
Definition: InlineAsm.h:240
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:4738
llvm::TargetLowering::AsmOperandInfo::ConstraintVT
MVT ConstraintVT
The ValueType for the operand value.
Definition: TargetLowering.h:4305
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1391
llvm::InlineAsm::Constraint_Unknown
@ Constraint_Unknown
Definition: InlineAsm.h:249
llvm::InlineAsm::isOutput
@ isOutput
Definition: InlineAsm.h:95
Instructions.h
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
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:732
llvm::InlineAsm::getNumOperandRegisters
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
Definition: InlineAsm.h:344
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:492
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::TargetLowering::getInlineAsmMemConstraint
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const
Definition: TargetLowering.h:4364
MachineOperand.h
getNumOpRegs
static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx)
Definition: InlineAsmLowering.cpp:235
llvm::InlineAsm::Extra_MayLoad
@ Extra_MayLoad
Definition: InlineAsm.h:231
llvm::TargetLoweringBase::getNumRegisters
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, Optional< MVT > RegisterVT=None) const
Return the number of registers that this ValueType will eventually require.
Definition: TargetLowering.h:1528
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1176
LLVMContext.h
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:661
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:505
llvm::TargetRegisterClass::end
iterator end() const
Definition: TargetRegisterInfo.h:76
llvm::RegState::EarlyClobber
@ EarlyClobber
Register definition happens before uses.
Definition: MachineInstrBuilder.h:54
llvm::TargetLoweringBase::getAsmOperandValueType
virtual EVT getAsmOperandValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Definition: TargetLowering.h:1430
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
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:4601
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:137
buildAnyextOrCopy
static bool buildAnyextOrCopy(Register Dst, Register Src, MachineIRBuilder &MIRBuilder)
Definition: InlineAsmLowering.cpp:240
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:4556
llvm::TargetLowering::AsmOperandInfoVector
std::vector< AsmOperandInfo > AsmOperandInfoVector
Definition: TargetLowering.h:4320
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:289
llvm::LLT
Definition: LowLevelTypeImpl.h:39