LLVM 17.0.0git
LanaiISelLowering.cpp
Go to the documentation of this file.
1//===-- LanaiISelLowering.cpp - Lanai DAG Lowering Implementation ---------===//
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// This file implements the LanaiTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "LanaiISelLowering.h"
14#include "Lanai.h"
15#include "LanaiCondCode.h"
17#include "LanaiSubtarget.h"
20#include "llvm/ADT/APInt.h"
21#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/StringRef.h"
35#include "llvm/IR/CallingConv.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GlobalValue.h"
42#include "llvm/Support/Debug.h"
49#include <cassert>
50#include <cmath>
51#include <cstdint>
52#include <cstdlib>
53#include <utility>
54
55#define DEBUG_TYPE "lanai-lower"
56
57using namespace llvm;
58
59// Limit on number of instructions the lowered multiplication may have before a
60// call to the library function should be generated instead. The threshold is
61// currently set to 14 as this was the smallest threshold that resulted in all
62// constant multiplications being lowered. A threshold of 5 covered all cases
63// except for one multiplication which required 14. mulsi3 requires 16
64// instructions (including the prologue and epilogue but excluding instructions
65// at call site). Until we can inline mulsi3, generating at most 14 instructions
66// will be faster than invoking mulsi3.
68 "lanai-constant-mul-threshold", cl::Hidden,
69 cl::desc("Maximum number of instruction to generate when lowering constant "
70 "multiplication instead of calling library function [default=14]"),
71 cl::init(14));
72
74 const LanaiSubtarget &STI)
76 // Set up the register classes.
77 addRegisterClass(MVT::i32, &Lanai::GPRRegClass);
78
79 // Compute derived properties from the register classes
80 TRI = STI.getRegisterInfo();
82
84
91
96
100
105
112
118
124
129
133
134 // Extended load operations for i1 types must be promoted
135 for (MVT VT : MVT::integer_valuetypes()) {
139 }
140
142
143 // Function alignments
146
147 setJumpIsExpensive(true);
148
149 // TODO: Setting the minimum jump table entries needed before a
150 // switch is transformed to a jump table to 100 to avoid creating jump tables
151 // as this was causing bad performance compared to a large group of if
152 // statements. Re-evaluate this on new benchmarks.
154
155 // Use fast calling convention for library functions.
156 for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) {
158 }
159
160 MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
162 MaxStoresPerMemcpy = 16; // For @llvm.memcpy -> sequence of stores
164 MaxStoresPerMemmove = 16; // For @llvm.memmove -> sequence of stores
166
167 // Booleans always contain 0 or 1.
169}
170
172 SelectionDAG &DAG) const {
173 switch (Op.getOpcode()) {
174 case ISD::MUL:
175 return LowerMUL(Op, DAG);
176 case ISD::BR_CC:
177 return LowerBR_CC(Op, DAG);
179 return LowerConstantPool(Op, DAG);
181 return LowerGlobalAddress(Op, DAG);
183 return LowerBlockAddress(Op, DAG);
184 case ISD::JumpTable:
185 return LowerJumpTable(Op, DAG);
186 case ISD::SELECT_CC:
187 return LowerSELECT_CC(Op, DAG);
188 case ISD::SETCC:
189 return LowerSETCC(Op, DAG);
190 case ISD::SHL_PARTS:
191 return LowerSHL_PARTS(Op, DAG);
192 case ISD::SRL_PARTS:
193 return LowerSRL_PARTS(Op, DAG);
194 case ISD::VASTART:
195 return LowerVASTART(Op, DAG);
197 return LowerDYNAMIC_STACKALLOC(Op, DAG);
198 case ISD::RETURNADDR:
199 return LowerRETURNADDR(Op, DAG);
200 case ISD::FRAMEADDR:
201 return LowerFRAMEADDR(Op, DAG);
202 default:
203 llvm_unreachable("unimplemented operand");
204 }
205}
206
207//===----------------------------------------------------------------------===//
208// Lanai Inline Assembly Support
209//===----------------------------------------------------------------------===//
210
212 const char *RegName, LLT /*VT*/,
213 const MachineFunction & /*MF*/) const {
214 // Only unallocatable registers should be matched here.
216 .Case("pc", Lanai::PC)
217 .Case("sp", Lanai::SP)
218 .Case("fp", Lanai::FP)
219 .Case("rr1", Lanai::RR1)
220 .Case("r10", Lanai::R10)
221 .Case("rr2", Lanai::RR2)
222 .Case("r11", Lanai::R11)
223 .Case("rca", Lanai::RCA)
224 .Default(0);
225
226 if (Reg)
227 return Reg;
228 report_fatal_error("Invalid register name global variable");
229}
230
231std::pair<unsigned, const TargetRegisterClass *>
233 StringRef Constraint,
234 MVT VT) const {
235 if (Constraint.size() == 1)
236 // GCC Constraint Letters
237 switch (Constraint[0]) {
238 case 'r': // GENERAL_REGS
239 return std::make_pair(0U, &Lanai::GPRRegClass);
240 default:
241 break;
242 }
243
245}
246
247// Examine constraint type and operand type and determine a weight value.
248// This object must already have been set up with the operand type
249// and the current alternative constraint selected.
252 AsmOperandInfo &Info, const char *Constraint) const {
254 Value *CallOperandVal = Info.CallOperandVal;
255 // If we don't have a value, we can't do a match,
256 // but allow it at the lowest weight.
257 if (CallOperandVal == nullptr)
258 return CW_Default;
259 // Look at the constraint type.
260 switch (*Constraint) {
261 case 'I': // signed 16 bit immediate
262 case 'J': // integer zero
263 case 'K': // unsigned 16 bit immediate
264 case 'L': // immediate in the range 0 to 31
265 case 'M': // signed 32 bit immediate where lower 16 bits are 0
266 case 'N': // signed 26 bit immediate
267 case 'O': // integer zero
268 if (isa<ConstantInt>(CallOperandVal))
269 Weight = CW_Constant;
270 break;
271 default:
273 break;
274 }
275 return Weight;
276}
277
278// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
279// vector. If it is invalid, don't add anything to Ops.
281 SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
282 SelectionDAG &DAG) const {
283 SDValue Result;
284
285 // Only support length 1 constraints for now.
286 if (Constraint.length() > 1)
287 return;
288
289 char ConstraintLetter = Constraint[0];
290 switch (ConstraintLetter) {
291 case 'I': // Signed 16 bit constant
292 // If this fails, the parent routine will give an error
293 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
294 if (isInt<16>(C->getSExtValue())) {
295 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
296 Op.getValueType());
297 break;
298 }
299 }
300 return;
301 case 'J': // integer zero
302 case 'O':
303 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
304 if (C->getZExtValue() == 0) {
305 Result = DAG.getTargetConstant(0, SDLoc(C), Op.getValueType());
306 break;
307 }
308 }
309 return;
310 case 'K': // unsigned 16 bit immediate
311 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
312 if (isUInt<16>(C->getZExtValue())) {
313 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
314 Op.getValueType());
315 break;
316 }
317 }
318 return;
319 case 'L': // immediate in the range 0 to 31
320 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
321 if (C->getZExtValue() <= 31) {
322 Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(C),
323 Op.getValueType());
324 break;
325 }
326 }
327 return;
328 case 'M': // signed 32 bit immediate where lower 16 bits are 0
329 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
330 int64_t Val = C->getSExtValue();
331 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)) {
332 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
333 break;
334 }
335 }
336 return;
337 case 'N': // signed 26 bit immediate
338 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
339 int64_t Val = C->getSExtValue();
340 if ((Val >= -33554432) && (Val <= 33554431)) {
341 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
342 break;
343 }
344 }
345 return;
346 default:
347 break; // This will fall through to the generic implementation
348 }
349
350 if (Result.getNode()) {
351 Ops.push_back(Result);
352 return;
353 }
354
355 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
356}
357
358//===----------------------------------------------------------------------===//
359// Calling Convention Implementation
360//===----------------------------------------------------------------------===//
361
362#include "LanaiGenCallingConv.inc"
363
364static unsigned NumFixedArgs;
365static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
366 CCValAssign::LocInfo LocInfo,
367 ISD::ArgFlagsTy ArgFlags, CCState &State) {
368 // Handle fixed arguments with default CC.
369 // Note: Both the default and fast CC handle VarArg the same and hence the
370 // calling convention of the function is not considered here.
371 if (ValNo < NumFixedArgs) {
372 return CC_Lanai32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State);
373 }
374
375 // Promote i8/i16 args to i32
376 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
377 LocVT = MVT::i32;
378 if (ArgFlags.isSExt())
379 LocInfo = CCValAssign::SExt;
380 else if (ArgFlags.isZExt())
381 LocInfo = CCValAssign::ZExt;
382 else
383 LocInfo = CCValAssign::AExt;
384 }
385
386 // VarArgs get passed on stack
387 unsigned Offset = State.AllocateStack(4, Align(4));
388 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
389 return false;
390}
391
392SDValue LanaiTargetLowering::LowerFormalArguments(
393 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
394 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
395 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
396 switch (CallConv) {
397 case CallingConv::C:
399 return LowerCCCArguments(Chain, CallConv, IsVarArg, Ins, DL, DAG, InVals);
400 default:
401 report_fatal_error("Unsupported calling convention");
402 }
403}
404
405SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
406 SmallVectorImpl<SDValue> &InVals) const {
407 SelectionDAG &DAG = CLI.DAG;
408 SDLoc &DL = CLI.DL;
410 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
412 SDValue Chain = CLI.Chain;
413 SDValue Callee = CLI.Callee;
414 bool &IsTailCall = CLI.IsTailCall;
415 CallingConv::ID CallConv = CLI.CallConv;
416 bool IsVarArg = CLI.IsVarArg;
417
418 // Lanai target does not yet support tail call optimization.
419 IsTailCall = false;
420
421 switch (CallConv) {
423 case CallingConv::C:
424 return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg, IsTailCall, Outs,
425 OutVals, Ins, DL, DAG, InVals);
426 default:
427 report_fatal_error("Unsupported calling convention");
428 }
429}
430
431// LowerCCCArguments - transform physical registers into virtual registers and
432// generate load operations for arguments places on the stack.
433SDValue LanaiTargetLowering::LowerCCCArguments(
434 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
435 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
436 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
438 MachineFrameInfo &MFI = MF.getFrameInfo();
441
442 // Assign locations to all of the incoming arguments.
444 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
445 *DAG.getContext());
446 if (CallConv == CallingConv::Fast) {
447 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32_Fast);
448 } else {
449 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32);
450 }
451
452 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
453 CCValAssign &VA = ArgLocs[i];
454 if (VA.isRegLoc()) {
455 // Arguments passed in registers
456 EVT RegVT = VA.getLocVT();
457 switch (RegVT.getSimpleVT().SimpleTy) {
458 case MVT::i32: {
459 Register VReg = RegInfo.createVirtualRegister(&Lanai::GPRRegClass);
460 RegInfo.addLiveIn(VA.getLocReg(), VReg);
461 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
462
463 // If this is an 8/16-bit value, it is really passed promoted to 32
464 // bits. Insert an assert[sz]ext to capture this, then truncate to the
465 // right size.
466 if (VA.getLocInfo() == CCValAssign::SExt)
467 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
468 DAG.getValueType(VA.getValVT()));
469 else if (VA.getLocInfo() == CCValAssign::ZExt)
470 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
471 DAG.getValueType(VA.getValVT()));
472
473 if (VA.getLocInfo() != CCValAssign::Full)
474 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
475
476 InVals.push_back(ArgValue);
477 break;
478 }
479 default:
480 LLVM_DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
481 << RegVT.getEVTString() << "\n");
482 llvm_unreachable("unhandled argument type");
483 }
484 } else {
485 // Only arguments passed on the stack should make it here.
486 assert(VA.isMemLoc());
487 // Load the argument to a virtual register
488 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
489 // Check that the argument fits in stack slot
490 if (ObjSize > 4) {
491 errs() << "LowerFormalArguments Unhandled argument type: "
492 << EVT(VA.getLocVT()).getEVTString() << "\n";
493 }
494 // Create the frame index object for this incoming parameter...
495 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
496
497 // Create the SelectionDAG nodes corresponding to a load
498 // from this parameter
499 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
500 InVals.push_back(DAG.getLoad(
501 VA.getLocVT(), DL, Chain, FIN,
503 }
504 }
505
506 // The Lanai ABI for returning structs by value requires that we copy
507 // the sret argument into rv for the return. Save the argument into
508 // a virtual register so that we can access it from the return points.
509 if (MF.getFunction().hasStructRetAttr()) {
510 Register Reg = LanaiMFI->getSRetReturnReg();
511 if (!Reg) {
513 LanaiMFI->setSRetReturnReg(Reg);
514 }
515 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
516 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
517 }
518
519 if (IsVarArg) {
520 // Record the frame index of the first variable argument
521 // which is a value necessary to VASTART.
522 int FI = MFI.CreateFixedObject(4, CCInfo.getNextStackOffset(), true);
523 LanaiMFI->setVarArgsFrameIndex(FI);
524 }
525
526 return Chain;
527}
528
530 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
531 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
533 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
534
535 return CCInfo.CheckReturn(Outs, RetCC_Lanai32);
536}
537
539LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
540 bool IsVarArg,
542 const SmallVectorImpl<SDValue> &OutVals,
543 const SDLoc &DL, SelectionDAG &DAG) const {
544 // CCValAssign - represent the assignment of the return value to a location
546
547 // CCState - Info about the registers and stack slot.
548 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
549 *DAG.getContext());
550
551 // Analize return values.
552 CCInfo.AnalyzeReturn(Outs, RetCC_Lanai32);
553
554 SDValue Flag;
555 SmallVector<SDValue, 4> RetOps(1, Chain);
556
557 // Copy the result values into the output registers.
558 for (unsigned i = 0; i != RVLocs.size(); ++i) {
559 CCValAssign &VA = RVLocs[i];
560 assert(VA.isRegLoc() && "Can only return in registers!");
561
562 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag);
563
564 // Guarantee that all emitted copies are stuck together with flags.
565 Flag = Chain.getValue(1);
566 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
567 }
568
569 // The Lanai ABI for returning structs by value requires that we copy
570 // the sret argument into rv for the return. We saved the argument into
571 // a virtual register in the entry block, so now we copy the value out
572 // and into rv.
576 Register Reg = LanaiMFI->getSRetReturnReg();
577 assert(Reg &&
578 "SRetReturnReg should have been set in LowerFormalArguments().");
579 SDValue Val =
580 DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout()));
581
582 Chain = DAG.getCopyToReg(Chain, DL, Lanai::RV, Val, Flag);
583 Flag = Chain.getValue(1);
584 RetOps.push_back(
585 DAG.getRegister(Lanai::RV, getPointerTy(DAG.getDataLayout())));
586 }
587
588 RetOps[0] = Chain; // Update chain
589
590 unsigned Opc = LanaiISD::RET_FLAG;
591 if (Flag.getNode())
592 RetOps.push_back(Flag);
593
594 // Return Void
595 return DAG.getNode(Opc, DL, MVT::Other,
596 ArrayRef<SDValue>(&RetOps[0], RetOps.size()));
597}
598
599// LowerCCCCallTo - functions arguments are copied from virtual regs to
600// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
601SDValue LanaiTargetLowering::LowerCCCCallTo(
602 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool IsVarArg,
603 bool /*IsTailCall*/, const SmallVectorImpl<ISD::OutputArg> &Outs,
604 const SmallVectorImpl<SDValue> &OutVals,
605 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
606 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
607 // Analyze operands of the call, assigning locations to each operand.
609 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
610 *DAG.getContext());
611 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
613
614 NumFixedArgs = 0;
615 if (IsVarArg && G) {
616 const Function *CalleeFn = dyn_cast<Function>(G->getGlobal());
617 if (CalleeFn)
619 }
620 if (NumFixedArgs)
621 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_VarArg);
622 else {
623 if (CallConv == CallingConv::Fast)
624 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_Fast);
625 else
626 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32);
627 }
628
629 // Get a count of how many bytes are to be pushed on the stack.
630 unsigned NumBytes = CCInfo.getNextStackOffset();
631
632 // Create local copies for byval args.
633 SmallVector<SDValue, 8> ByValArgs;
634 for (unsigned I = 0, E = Outs.size(); I != E; ++I) {
635 ISD::ArgFlagsTy Flags = Outs[I].Flags;
636 if (!Flags.isByVal())
637 continue;
638
639 SDValue Arg = OutVals[I];
640 unsigned Size = Flags.getByValSize();
641 Align Alignment = Flags.getNonZeroByValAlign();
642
643 int FI = MFI.CreateStackObject(Size, Alignment, false);
644 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
645 SDValue SizeNode = DAG.getConstant(Size, DL, MVT::i32);
646
647 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
648 /*IsVolatile=*/false,
649 /*AlwaysInline=*/false,
650 /*isTailCall=*/false, MachinePointerInfo(),
652 ByValArgs.push_back(FIPtr);
653 }
654
655 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
656
658 SmallVector<SDValue, 12> MemOpChains;
660
661 // Walk the register/memloc assignments, inserting copies/loads.
662 for (unsigned I = 0, J = 0, E = ArgLocs.size(); I != E; ++I) {
663 CCValAssign &VA = ArgLocs[I];
664 SDValue Arg = OutVals[I];
665 ISD::ArgFlagsTy Flags = Outs[I].Flags;
666
667 // Promote the value if needed.
668 switch (VA.getLocInfo()) {
670 break;
672 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
673 break;
675 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
676 break;
678 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
679 break;
680 default:
681 llvm_unreachable("Unknown loc info!");
682 }
683
684 // Use local copy if it is a byval arg.
685 if (Flags.isByVal())
686 Arg = ByValArgs[J++];
687
688 // Arguments that can be passed on register must be kept at RegsToPass
689 // vector
690 if (VA.isRegLoc()) {
691 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
692 } else {
693 assert(VA.isMemLoc());
694
695 if (StackPtr.getNode() == nullptr)
696 StackPtr = DAG.getCopyFromReg(Chain, DL, Lanai::SP,
698
699 SDValue PtrOff =
700 DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr,
702
703 MemOpChains.push_back(
704 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
705 }
706 }
707
708 // Transform all store nodes into one single node because all store nodes are
709 // independent of each other.
710 if (!MemOpChains.empty())
712 ArrayRef<SDValue>(&MemOpChains[0], MemOpChains.size()));
713
714 SDValue InFlag;
715
716 // Build a sequence of copy-to-reg nodes chained together with token chain and
717 // flag operands which copy the outgoing args into registers. The InFlag in
718 // necessary since all emitted instructions must be stuck together.
719 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
720 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[I].first,
721 RegsToPass[I].second, InFlag);
722 InFlag = Chain.getValue(1);
723 }
724
725 // If the callee is a GlobalAddress node (quite common, every direct call is)
726 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
727 // Likewise ExternalSymbol -> TargetExternalSymbol.
728 uint8_t OpFlag = LanaiII::MO_NO_FLAG;
729 if (G) {
731 G->getGlobal(), DL, getPointerTy(DAG.getDataLayout()), 0, OpFlag);
732 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
734 E->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlag);
735 }
736
737 // Returns a chain & a flag for retval copy to use.
738 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
740 Ops.push_back(Chain);
741 Ops.push_back(Callee);
742
743 // Add a register mask operand representing the call-preserved registers.
744 // TODO: Should return-twice functions be handled?
745 const uint32_t *Mask =
746 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
747 assert(Mask && "Missing call preserved mask for calling convention");
748 Ops.push_back(DAG.getRegisterMask(Mask));
749
750 // Add argument registers to the end of the list so that they are
751 // known live into the call.
752 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I)
753 Ops.push_back(DAG.getRegister(RegsToPass[I].first,
754 RegsToPass[I].second.getValueType()));
755
756 if (InFlag.getNode())
757 Ops.push_back(InFlag);
758
759 Chain = DAG.getNode(LanaiISD::CALL, DL, NodeTys,
760 ArrayRef<SDValue>(&Ops[0], Ops.size()));
761 InFlag = Chain.getValue(1);
762
763 // Create the CALLSEQ_END node.
764 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InFlag, DL);
765 InFlag = Chain.getValue(1);
766
767 // Handle result values, copying them out of physregs into vregs that we
768 // return.
769 return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, DL, DAG,
770 InVals);
771}
772
773// LowerCallResult - Lower the result values of a call into the
774// appropriate copies out of appropriate physical registers.
775SDValue LanaiTargetLowering::LowerCallResult(
776 SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg,
777 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
778 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
779 // Assign locations to each value returned by this call.
781 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
782 *DAG.getContext());
783
784 CCInfo.AnalyzeCallResult(Ins, RetCC_Lanai32);
785
786 // Copy all of the result registers out of their specified physreg.
787 for (unsigned I = 0; I != RVLocs.size(); ++I) {
788 Chain = DAG.getCopyFromReg(Chain, DL, RVLocs[I].getLocReg(),
789 RVLocs[I].getValVT(), InFlag)
790 .getValue(1);
791 InFlag = Chain.getValue(2);
792 InVals.push_back(Chain.getValue(0));
793 }
794
795 return Chain;
796}
797
798//===----------------------------------------------------------------------===//
799// Custom Lowerings
800//===----------------------------------------------------------------------===//
801
803 SDValue &RHS, SelectionDAG &DAG) {
804 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
805
806 // For integer, only the SETEQ, SETNE, SETLT, SETLE, SETGT, SETGE, SETULT,
807 // SETULE, SETUGT, and SETUGE opcodes are used (see CodeGen/ISDOpcodes.h)
808 // and Lanai only supports integer comparisons, so only provide definitions
809 // for them.
810 switch (SetCCOpcode) {
811 case ISD::SETEQ:
812 return LPCC::ICC_EQ;
813 case ISD::SETGT:
814 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
815 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
816 // X > -1 -> X >= 0 -> is_plus(X)
817 RHS = DAG.getConstant(0, DL, RHS.getValueType());
818 return LPCC::ICC_PL;
819 }
820 return LPCC::ICC_GT;
821 case ISD::SETUGT:
822 return LPCC::ICC_UGT;
823 case ISD::SETLT:
824 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
825 if (RHSC->getZExtValue() == 0)
826 // X < 0 -> is_minus(X)
827 return LPCC::ICC_MI;
828 return LPCC::ICC_LT;
829 case ISD::SETULT:
830 return LPCC::ICC_ULT;
831 case ISD::SETLE:
832 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
833 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
834 // X <= -1 -> X < 0 -> is_minus(X)
835 RHS = DAG.getConstant(0, DL, RHS.getValueType());
836 return LPCC::ICC_MI;
837 }
838 return LPCC::ICC_LE;
839 case ISD::SETULE:
840 return LPCC::ICC_ULE;
841 case ISD::SETGE:
842 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
843 if (RHSC->getZExtValue() == 0)
844 // X >= 0 -> is_plus(X)
845 return LPCC::ICC_PL;
846 return LPCC::ICC_GE;
847 case ISD::SETUGE:
848 return LPCC::ICC_UGE;
849 case ISD::SETNE:
850 return LPCC::ICC_NE;
851 case ISD::SETONE:
852 case ISD::SETUNE:
853 case ISD::SETOGE:
854 case ISD::SETOLE:
855 case ISD::SETOLT:
856 case ISD::SETOGT:
857 case ISD::SETOEQ:
858 case ISD::SETUEQ:
859 case ISD::SETO:
860 case ISD::SETUO:
861 llvm_unreachable("Unsupported comparison.");
862 default:
863 llvm_unreachable("Unknown integer condition code!");
864 }
865}
866
868 SDValue Chain = Op.getOperand(0);
869 SDValue Cond = Op.getOperand(1);
870 SDValue LHS = Op.getOperand(2);
871 SDValue RHS = Op.getOperand(3);
872 SDValue Dest = Op.getOperand(4);
873 SDLoc DL(Op);
874
876 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
877 SDValue Flag =
878 DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
879
880 return DAG.getNode(LanaiISD::BR_CC, DL, Op.getValueType(), Chain, Dest,
881 TargetCC, Flag);
882}
883
885 EVT VT = Op->getValueType(0);
886 if (VT != MVT::i32)
887 return SDValue();
888
889 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op->getOperand(1));
890 if (!C)
891 return SDValue();
892
893 int64_t MulAmt = C->getSExtValue();
894 int32_t HighestOne = -1;
895 uint32_t NonzeroEntries = 0;
896 int SignedDigit[32] = {0};
897
898 // Convert to non-adjacent form (NAF) signed-digit representation.
899 // NAF is a signed-digit form where no adjacent digits are non-zero. It is the
900 // minimal Hamming weight representation of a number (on average 1/3 of the
901 // digits will be non-zero vs 1/2 for regular binary representation). And as
902 // the non-zero digits will be the only digits contributing to the instruction
903 // count, this is desirable. The next loop converts it to NAF (following the
904 // approach in 'Guide to Elliptic Curve Cryptography' [ISBN: 038795273X]) by
905 // choosing the non-zero coefficients such that the resulting quotient is
906 // divisible by 2 which will cause the next coefficient to be zero.
907 int64_t E = std::abs(MulAmt);
908 int S = (MulAmt < 0 ? -1 : 1);
909 int I = 0;
910 while (E > 0) {
911 int ZI = 0;
912 if (E % 2 == 1) {
913 ZI = 2 - (E % 4);
914 if (ZI != 0)
915 ++NonzeroEntries;
916 }
917 SignedDigit[I] = S * ZI;
918 if (SignedDigit[I] == 1)
919 HighestOne = I;
920 E = (E - ZI) / 2;
921 ++I;
922 }
923
924 // Compute number of instructions required. Due to differences in lowering
925 // between the different processors this count is not exact.
926 // Start by assuming a shift and a add/sub for every non-zero entry (hence
927 // every non-zero entry requires 1 shift and 1 add/sub except for the first
928 // entry).
929 int32_t InstrRequired = 2 * NonzeroEntries - 1;
930 // Correct possible over-adding due to shift by 0 (which is not emitted).
931 if (std::abs(MulAmt) % 2 == 1)
932 --InstrRequired;
933 // Return if the form generated would exceed the instruction threshold.
934 if (InstrRequired > LanaiLowerConstantMulThreshold)
935 return SDValue();
936
937 SDValue Res;
938 SDLoc DL(Op);
939 SDValue V = Op->getOperand(0);
940
941 // Initialize the running sum. Set the running sum to the maximal shifted
942 // positive value (i.e., largest i such that zi == 1 and MulAmt has V<<i as a
943 // term NAF).
944 if (HighestOne == -1)
945 Res = DAG.getConstant(0, DL, MVT::i32);
946 else {
947 Res = DAG.getNode(ISD::SHL, DL, VT, V,
948 DAG.getConstant(HighestOne, DL, MVT::i32));
949 SignedDigit[HighestOne] = 0;
950 }
951
952 // Assemble multiplication from shift, add, sub using NAF form and running
953 // sum.
954 for (unsigned int I = 0; I < std::size(SignedDigit); ++I) {
955 if (SignedDigit[I] == 0)
956 continue;
957
958 // Shifted multiplicand (v<<i).
959 SDValue Op =
960 DAG.getNode(ISD::SHL, DL, VT, V, DAG.getConstant(I, DL, MVT::i32));
961 if (SignedDigit[I] == 1)
962 Res = DAG.getNode(ISD::ADD, DL, VT, Res, Op);
963 else if (SignedDigit[I] == -1)
964 Res = DAG.getNode(ISD::SUB, DL, VT, Res, Op);
965 }
966 return Res;
967}
968
970 SDValue LHS = Op.getOperand(0);
971 SDValue RHS = Op.getOperand(1);
972 SDValue Cond = Op.getOperand(2);
973 SDLoc DL(Op);
974
976 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
977 SDValue Flag =
978 DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
979
980 return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Flag);
981}
982
984 SelectionDAG &DAG) const {
985 SDValue LHS = Op.getOperand(0);
986 SDValue RHS = Op.getOperand(1);
987 SDValue TrueV = Op.getOperand(2);
988 SDValue FalseV = Op.getOperand(3);
989 SDValue Cond = Op.getOperand(4);
990 SDLoc DL(Op);
991
993 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
994 SDValue Flag =
995 DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
996
997 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
998 return DAG.getNode(LanaiISD::SELECT_CC, DL, VTs, TrueV, FalseV, TargetCC,
999 Flag);
1000}
1001
1005
1006 SDLoc DL(Op);
1007 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1009
1010 // vastart just stores the address of the VarArgsFrameIndex slot into the
1011 // memory location argument.
1012 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1013 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1014 MachinePointerInfo(SV));
1015}
1016
1018 SelectionDAG &DAG) const {
1019 SDValue Chain = Op.getOperand(0);
1020 SDValue Size = Op.getOperand(1);
1021 SDLoc DL(Op);
1022
1024
1025 // Get a reference to the stack pointer.
1026 SDValue StackPointer = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1027
1028 // Subtract the dynamic size from the actual stack size to
1029 // obtain the new stack size.
1030 SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i32, StackPointer, Size);
1031
1032 // For Lanai, the outgoing memory arguments area should be on top of the
1033 // alloca area on the stack i.e., the outgoing memory arguments should be
1034 // at a lower address than the alloca area. Move the alloca area down the
1035 // stack by adding back the space reserved for outgoing arguments to SP
1036 // here.
1037 //
1038 // We do not know what the size of the outgoing args is at this point.
1039 // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
1040 // stack pointer. We replace this instruction with on that has the correct,
1041 // known offset in emitPrologue().
1042 SDValue ArgAdjust = DAG.getNode(LanaiISD::ADJDYNALLOC, DL, MVT::i32, Sub);
1043
1044 // The Sub result contains the new stack start address, so it
1045 // must be placed in the stack pointer register.
1046 SDValue CopyChain = DAG.getCopyToReg(Chain, DL, SPReg, Sub);
1047
1048 SDValue Ops[2] = {ArgAdjust, CopyChain};
1049 return DAG.getMergeValues(Ops, DL);
1050}
1051
1053 SelectionDAG &DAG) const {
1055 MachineFrameInfo &MFI = MF.getFrameInfo();
1056 MFI.setReturnAddressIsTaken(true);
1057
1058 EVT VT = Op.getValueType();
1059 SDLoc DL(Op);
1060 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1061 if (Depth) {
1062 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1063 const unsigned Offset = -4;
1064 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1066 return DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1067 }
1068
1069 // Return the link register, which contains the return address.
1070 // Mark it an implicit live-in.
1072 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
1073}
1074
1076 SelectionDAG &DAG) const {
1078 MFI.setFrameAddressIsTaken(true);
1079
1080 EVT VT = Op.getValueType();
1081 SDLoc DL(Op);
1082 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Lanai::FP, VT);
1083 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1084 while (Depth--) {
1085 const unsigned Offset = -8;
1086 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1088 FrameAddr =
1089 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1090 }
1091 return FrameAddr;
1092}
1093
1094const char *LanaiTargetLowering::getTargetNodeName(unsigned Opcode) const {
1095 switch (Opcode) {
1097 return "LanaiISD::ADJDYNALLOC";
1098 case LanaiISD::RET_FLAG:
1099 return "LanaiISD::RET_FLAG";
1100 case LanaiISD::CALL:
1101 return "LanaiISD::CALL";
1103 return "LanaiISD::SELECT_CC";
1104 case LanaiISD::SETCC:
1105 return "LanaiISD::SETCC";
1106 case LanaiISD::SUBBF:
1107 return "LanaiISD::SUBBF";
1108 case LanaiISD::SET_FLAG:
1109 return "LanaiISD::SET_FLAG";
1110 case LanaiISD::BR_CC:
1111 return "LanaiISD::BR_CC";
1112 case LanaiISD::Wrapper:
1113 return "LanaiISD::Wrapper";
1114 case LanaiISD::HI:
1115 return "LanaiISD::HI";
1116 case LanaiISD::LO:
1117 return "LanaiISD::LO";
1118 case LanaiISD::SMALL:
1119 return "LanaiISD::SMALL";
1120 default:
1121 return nullptr;
1122 }
1123}
1124
1126 SelectionDAG &DAG) const {
1127 SDLoc DL(Op);
1128 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1129 const Constant *C = N->getConstVal();
1130 const LanaiTargetObjectFile *TLOF =
1131 static_cast<const LanaiTargetObjectFile *>(
1133
1134 // If the code model is small or constant will be placed in the small section,
1135 // then assume address will fit in 21-bits.
1138 SDValue Small = DAG.getTargetConstantPool(
1139 C, MVT::i32, N->getAlign(), N->getOffset(), LanaiII::MO_NO_FLAG);
1140 return DAG.getNode(ISD::OR, DL, MVT::i32,
1141 DAG.getRegister(Lanai::R0, MVT::i32),
1142 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1143 } else {
1144 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1145 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1146
1147 SDValue Hi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1148 N->getOffset(), OpFlagHi);
1149 SDValue Lo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1150 N->getOffset(), OpFlagLo);
1151 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1152 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1153 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1154 return Result;
1155 }
1156}
1157
1159 SelectionDAG &DAG) const {
1160 SDLoc DL(Op);
1161 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1162 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1163
1164 const LanaiTargetObjectFile *TLOF =
1165 static_cast<const LanaiTargetObjectFile *>(
1167
1168 // If the code model is small or global variable will be placed in the small
1169 // section, then assume address will fit in 21-bits.
1170 const GlobalObject *GO = GV->getAliaseeObject();
1171 if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
1172 SDValue Small = DAG.getTargetGlobalAddress(
1174 return DAG.getNode(ISD::OR, DL, MVT::i32,
1175 DAG.getRegister(Lanai::R0, MVT::i32),
1176 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1177 } else {
1178 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1179 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1180
1181 // Create the TargetGlobalAddress node, folding in the constant offset.
1183 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagHi);
1185 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagLo);
1186 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1187 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1188 return DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1189 }
1190}
1191
1193 SelectionDAG &DAG) const {
1194 SDLoc DL(Op);
1195 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1196
1197 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1198 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1199
1200 SDValue Hi = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagHi);
1201 SDValue Lo = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagLo);
1202 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1203 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1204 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1205 return Result;
1206}
1207
1209 SelectionDAG &DAG) const {
1210 SDLoc DL(Op);
1211 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1212
1213 // If the code model is small assume address will fit in 21-bits.
1214 if (getTargetMachine().getCodeModel() == CodeModel::Small) {
1215 SDValue Small = DAG.getTargetJumpTable(
1216 JT->getIndex(), getPointerTy(DAG.getDataLayout()), LanaiII::MO_NO_FLAG);
1217 return DAG.getNode(ISD::OR, DL, MVT::i32,
1218 DAG.getRegister(Lanai::R0, MVT::i32),
1219 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1220 } else {
1221 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1222 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1223
1225 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagHi);
1227 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagLo);
1228 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1229 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1230 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1231 return Result;
1232 }
1233}
1234
1236 SelectionDAG &DAG) const {
1237 EVT VT = Op.getValueType();
1238 unsigned VTBits = VT.getSizeInBits();
1239 SDLoc dl(Op);
1240 assert(Op.getNumOperands() == 3 && "Unexpected SHL!");
1241 SDValue ShOpLo = Op.getOperand(0);
1242 SDValue ShOpHi = Op.getOperand(1);
1243 SDValue ShAmt = Op.getOperand(2);
1244
1245 // Performs the following for (ShOpLo + (ShOpHi << 32)) << ShAmt:
1246 // LoBitsForHi = (ShAmt == 0) ? 0 : (ShOpLo >> (32-ShAmt))
1247 // HiBitsForHi = ShOpHi << ShAmt
1248 // Hi = (ShAmt >= 32) ? (ShOpLo << (ShAmt-32)) : (LoBitsForHi | HiBitsForHi)
1249 // Lo = (ShAmt >= 32) ? 0 : (ShOpLo << ShAmt)
1250 // return (Hi << 32) | Lo;
1251
1252 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
1253 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1254 SDValue LoBitsForHi = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
1255
1256 // If ShAmt == 0, we just calculated "(SRL ShOpLo, 32)" which is "undef". We
1257 // wanted 0, so CSEL it directly.
1258 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1259 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1260 LoBitsForHi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, LoBitsForHi);
1261
1262 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
1263 DAG.getConstant(VTBits, dl, MVT::i32));
1264 SDValue HiBitsForHi = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
1265 SDValue HiForNormalShift =
1266 DAG.getNode(ISD::OR, dl, VT, LoBitsForHi, HiBitsForHi);
1267
1268 SDValue HiForBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
1269
1270 SetCC = DAG.getSetCC(dl, MVT::i32, ExtraShAmt, Zero, ISD::SETGE);
1271 SDValue Hi =
1272 DAG.getSelect(dl, MVT::i32, SetCC, HiForBigShift, HiForNormalShift);
1273
1274 // Lanai shifts of larger than register sizes are wrapped rather than
1275 // clamped, so we can't just emit "lo << b" if b is too big.
1276 SDValue LoForNormalShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
1277 SDValue Lo = DAG.getSelect(
1278 dl, MVT::i32, SetCC, DAG.getConstant(0, dl, MVT::i32), LoForNormalShift);
1279
1280 SDValue Ops[2] = {Lo, Hi};
1281 return DAG.getMergeValues(Ops, dl);
1282}
1283
1285 SelectionDAG &DAG) const {
1286 MVT VT = Op.getSimpleValueType();
1287 unsigned VTBits = VT.getSizeInBits();
1288 SDLoc dl(Op);
1289 SDValue ShOpLo = Op.getOperand(0);
1290 SDValue ShOpHi = Op.getOperand(1);
1291 SDValue ShAmt = Op.getOperand(2);
1292
1293 // Performs the following for a >> b:
1294 // unsigned r_high = a_high >> b;
1295 // r_high = (32 - b <= 0) ? 0 : r_high;
1296 //
1297 // unsigned r_low = a_low >> b;
1298 // r_low = (32 - b <= 0) ? r_high : r_low;
1299 // r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
1300 // return (unsigned long long)r_high << 32 | r_low;
1301 // Note: This takes advantage of Lanai's shift behavior to avoid needing to
1302 // mask the shift amount.
1303
1304 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1305 SDValue NegatedPlus32 = DAG.getNode(
1306 ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1307 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
1308
1309 SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
1310 Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
1311
1312 SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
1313 Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
1314 SDValue CarryBits =
1315 DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
1316 SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1317 Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
1318 DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
1319
1320 SDValue Ops[2] = {Lo, Hi};
1321 return DAG.getMergeValues(Ops, dl);
1322}
1323
1324// Helper function that checks if N is a null or all ones constant.
1325static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
1326 return AllOnes ? isAllOnesConstant(N) : isNullConstant(N);
1327}
1328
1329// Return true if N is conditionally 0 or all ones.
1330// Detects these expressions where cc is an i1 value:
1331//
1332// (select cc 0, y) [AllOnes=0]
1333// (select cc y, 0) [AllOnes=0]
1334// (zext cc) [AllOnes=0]
1335// (sext cc) [AllOnes=0/1]
1336// (select cc -1, y) [AllOnes=1]
1337// (select cc y, -1) [AllOnes=1]
1338//
1339// * AllOnes determines whether to check for an all zero (AllOnes false) or an
1340// all ones operand (AllOnes true).
1341// * Invert is set when N is the all zero/ones constant when CC is false.
1342// * OtherOp is set to the alternative value of N.
1343//
1344// For example, for (select cc X, Y) and AllOnes = 0 if:
1345// * X = 0, Invert = False and OtherOp = Y
1346// * Y = 0, Invert = True and OtherOp = X
1347static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC,
1348 bool &Invert, SDValue &OtherOp,
1349 SelectionDAG &DAG) {
1350 switch (N->getOpcode()) {
1351 default:
1352 return false;
1353 case ISD::SELECT: {
1354 CC = N->getOperand(0);
1355 SDValue N1 = N->getOperand(1);
1356 SDValue N2 = N->getOperand(2);
1357 if (isZeroOrAllOnes(N1, AllOnes)) {
1358 Invert = false;
1359 OtherOp = N2;
1360 return true;
1361 }
1362 if (isZeroOrAllOnes(N2, AllOnes)) {
1363 Invert = true;
1364 OtherOp = N1;
1365 return true;
1366 }
1367 return false;
1368 }
1369 case ISD::ZERO_EXTEND: {
1370 // (zext cc) can never be the all ones value.
1371 if (AllOnes)
1372 return false;
1373 CC = N->getOperand(0);
1374 if (CC.getValueType() != MVT::i1)
1375 return false;
1376 SDLoc dl(N);
1377 EVT VT = N->getValueType(0);
1378 OtherOp = DAG.getConstant(1, dl, VT);
1379 Invert = true;
1380 return true;
1381 }
1382 case ISD::SIGN_EXTEND: {
1383 CC = N->getOperand(0);
1384 if (CC.getValueType() != MVT::i1)
1385 return false;
1386 SDLoc dl(N);
1387 EVT VT = N->getValueType(0);
1388 Invert = !AllOnes;
1389 if (AllOnes)
1390 // When looking for an AllOnes constant, N is an sext, and the 'other'
1391 // value is 0.
1392 OtherOp = DAG.getConstant(0, dl, VT);
1393 else
1394 OtherOp = DAG.getAllOnesConstant(dl, VT);
1395 return true;
1396 }
1397 }
1398}
1399
1400// Combine a constant select operand into its use:
1401//
1402// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
1403// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1404// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
1405// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
1406// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
1407//
1408// The transform is rejected if the select doesn't have a constant operand that
1409// is null, or all ones when AllOnes is set.
1410//
1411// Also recognize sext/zext from i1:
1412//
1413// (add (zext cc), x) -> (select cc (add x, 1), x)
1414// (add (sext cc), x) -> (select cc (add x, -1), x)
1415//
1416// These transformations eventually create predicated instructions.
1419 bool AllOnes) {
1420 SelectionDAG &DAG = DCI.DAG;
1421 EVT VT = N->getValueType(0);
1422 SDValue NonConstantVal;
1423 SDValue CCOp;
1424 bool SwapSelectOps;
1425 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
1426 NonConstantVal, DAG))
1427 return SDValue();
1428
1429 // Slct is now know to be the desired identity constant when CC is true.
1430 SDValue TrueVal = OtherOp;
1431 SDValue FalseVal =
1432 DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
1433 // Unless SwapSelectOps says CC should be false.
1434 if (SwapSelectOps)
1435 std::swap(TrueVal, FalseVal);
1436
1437 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
1438}
1439
1440// Attempt combineSelectAndUse on each operand of a commutative operator N.
1441static SDValue
1443 bool AllOnes) {
1444 SDValue N0 = N->getOperand(0);
1445 SDValue N1 = N->getOperand(1);
1446 if (N0.getNode()->hasOneUse())
1447 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
1448 return Result;
1449 if (N1.getNode()->hasOneUse())
1450 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
1451 return Result;
1452 return SDValue();
1453}
1454
1455// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
1458 SDValue N0 = N->getOperand(0);
1459 SDValue N1 = N->getOperand(1);
1460
1461 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1462 if (N1.getNode()->hasOneUse())
1463 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
1464 return Result;
1465
1466 return SDValue();
1467}
1468
1470 DAGCombinerInfo &DCI) const {
1471 switch (N->getOpcode()) {
1472 default:
1473 break;
1474 case ISD::ADD:
1475 case ISD::OR:
1476 case ISD::XOR:
1477 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
1478 case ISD::AND:
1479 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
1480 case ISD::SUB:
1481 return PerformSUBCombine(N, DCI);
1482 }
1483
1484 return SDValue();
1485}
1486
1488 const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
1489 const SelectionDAG &DAG, unsigned Depth) const {
1490 unsigned BitWidth = Known.getBitWidth();
1491 switch (Op.getOpcode()) {
1492 default:
1493 break;
1494 case LanaiISD::SETCC:
1495 Known = KnownBits(BitWidth);
1496 Known.Zero.setBits(1, BitWidth);
1497 break;
1499 KnownBits Known2;
1500 Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
1501 Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
1502 Known = KnownBits::commonBits(Known, Known2);
1503 break;
1504 }
1505}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isZeroOrAllOnes(SDValue N, bool AllOnes)
static SDValue PerformSUBCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
static SDValue combineSelectAndUseCommutative(SDNode *N, bool AllOnes, TargetLowering::DAGCombinerInfo &DCI)
static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC, bool &Invert, SDValue &OtherOp, SelectionDAG &DAG)
static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, TargetLowering::DAGCombinerInfo &DCI, bool AllOnes=false)
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
#define RegName(no)
static unsigned NumFixedArgs
static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static LPCC::CondCode IntCondCCodeToICC(SDValue CC, const SDLoc &DL, SDValue &RHS, SelectionDAG &DAG)
static cl::opt< int > LanaiLowerConstantMulThreshold("lanai-constant-mul-threshold", cl::Hidden, cl::desc("Maximum number of instruction to generate when lowering constant " "multiplication instead of calling library function [default=14]"), cl::init(14))
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
unsigned const TargetRegisterInfo * TRI
LLVMContext & Context
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:75
void setBits(unsigned loBit, unsigned hiBit)
Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
Definition: APInt.h:1345
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
The address of a basic block.
Definition: Constants.h:875
CCState - This class holds information needed while lowering arguments and return values.
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
This is an important base class in LLVM.
Definition: Constant.h:41
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:139
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:174
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:625
const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:369
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
const LanaiRegisterInfo * getRegisterInfo() const override
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
LanaiTargetLowering(const TargetMachine &TM, const LanaiSubtarget &STI)
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info, const char *Constraint) const override
Examine constraint string and operand type and determine a weight value.
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
bool isConstantInSmallSection(const DataLayout &DL, const Constant *CN) const
Return true if this constant should be placed into small data section.
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool hasOneUse() const
Return true if there is exactly one use of this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:221
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:717
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:727
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:468
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
Definition: SelectionDAG.h:656
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:769
SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, bool isTarget=false, unsigned TargetFlags=0)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:671
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:465
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:795
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:481
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:733
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:550
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
virtual TargetLoweringObjectFile * getObjFileLowering() const
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:736
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1056
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1052
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:700
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1085
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:766
@ RETURNADDR
Definition: ISDOpcodes.h:95
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:760
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1007
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:990
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:713
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1081
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:637
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:691
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:763
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:728
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:975
@ ConstantPool
Definition: ISDOpcodes.h:82
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:781
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:666
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:769
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1076
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1000
@ BlockAddress
Definition: ISDOpcodes.h:84
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:749
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1428
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:148
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:147
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:34
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:340
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:288
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
Definition: ValueTypes.cpp:152
static KnownBits commonBits(const KnownBits &LHS, const KnownBits &RHS)
Compute known bits common to LHS and RHS.
Definition: KnownBits.h:315
unsigned getBitWidth() const
Get the bit width of this value.
Definition: KnownBits.h:40
unsigned getRARegister() const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals