LLVM 20.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 "LanaiCondCode.h"
16#include "LanaiSubtarget.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/StringRef.h"
34#include "llvm/IR/CallingConv.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/GlobalValue.h"
41#include "llvm/Support/Debug.h"
47#include <cassert>
48#include <cmath>
49#include <cstdint>
50#include <cstdlib>
51#include <utility>
52
53#define DEBUG_TYPE "lanai-lower"
54
55using namespace llvm;
56
57// Limit on number of instructions the lowered multiplication may have before a
58// call to the library function should be generated instead. The threshold is
59// currently set to 14 as this was the smallest threshold that resulted in all
60// constant multiplications being lowered. A threshold of 5 covered all cases
61// except for one multiplication which required 14. mulsi3 requires 16
62// instructions (including the prologue and epilogue but excluding instructions
63// at call site). Until we can inline mulsi3, generating at most 14 instructions
64// will be faster than invoking mulsi3.
66 "lanai-constant-mul-threshold", cl::Hidden,
67 cl::desc("Maximum number of instruction to generate when lowering constant "
68 "multiplication instead of calling library function [default=14]"),
69 cl::init(14));
70
72 const LanaiSubtarget &STI)
73 : TargetLowering(TM) {
74 // Set up the register classes.
75 addRegisterClass(MVT::i32, &Lanai::GPRRegClass);
76
77 // Compute derived properties from the register classes
78 TRI = STI.getRegisterInfo();
80
82
89
94
98
103
110
116
122
127
131
132 // Extended load operations for i1 types must be promoted
133 for (MVT VT : MVT::integer_valuetypes()) {
137 }
138
140
141 // Function alignments
144
145 setJumpIsExpensive(true);
146
147 // TODO: Setting the minimum jump table entries needed before a
148 // switch is transformed to a jump table to 100 to avoid creating jump tables
149 // as this was causing bad performance compared to a large group of if
150 // statements. Re-evaluate this on new benchmarks.
152
153 // Use fast calling convention for library functions.
154 for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) {
156 }
157
158 MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
160 MaxStoresPerMemcpy = 16; // For @llvm.memcpy -> sequence of stores
162 MaxStoresPerMemmove = 16; // For @llvm.memmove -> sequence of stores
164
165 // Booleans always contain 0 or 1.
167
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, StringRef Constraint, std::vector<SDValue> &Ops,
282 SelectionDAG &DAG) const {
283 SDValue Result;
284
285 // Only support length 1 constraints for now.
286 if (Constraint.size() > 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
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 (const CCValAssign &VA : ArgLocs) {
453 if (VA.isRegLoc()) {
454 // Arguments passed in registers
455 EVT RegVT = VA.getLocVT();
456 switch (RegVT.getSimpleVT().SimpleTy) {
457 case MVT::i32: {
458 Register VReg = RegInfo.createVirtualRegister(&Lanai::GPRRegClass);
459 RegInfo.addLiveIn(VA.getLocReg(), VReg);
460 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
461
462 // If this is an 8/16-bit value, it is really passed promoted to 32
463 // bits. Insert an assert[sz]ext to capture this, then truncate to the
464 // right size.
465 if (VA.getLocInfo() == CCValAssign::SExt)
466 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
467 DAG.getValueType(VA.getValVT()));
468 else if (VA.getLocInfo() == CCValAssign::ZExt)
469 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
470 DAG.getValueType(VA.getValVT()));
471
472 if (VA.getLocInfo() != CCValAssign::Full)
473 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
474
475 InVals.push_back(ArgValue);
476 break;
477 }
478 default:
479 LLVM_DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
480 << RegVT << "\n");
481 llvm_unreachable("unhandled argument type");
482 }
483 } else {
484 // Only arguments passed on the stack should make it here.
485 assert(VA.isMemLoc());
486 // Load the argument to a virtual register
487 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
488 // Check that the argument fits in stack slot
489 if (ObjSize > 4) {
490 errs() << "LowerFormalArguments Unhandled argument type: "
491 << VA.getLocVT() << "\n";
492 }
493 // Create the frame index object for this incoming parameter...
494 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
495
496 // Create the SelectionDAG nodes corresponding to a load
497 // from this parameter
498 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
499 InVals.push_back(DAG.getLoad(
500 VA.getLocVT(), DL, Chain, FIN,
502 }
503 }
504
505 // The Lanai ABI for returning structs by value requires that we copy
506 // the sret argument into rv for the return. Save the argument into
507 // a virtual register so that we can access it from the return points.
508 if (MF.getFunction().hasStructRetAttr()) {
509 Register Reg = LanaiMFI->getSRetReturnReg();
510 if (!Reg) {
512 LanaiMFI->setSRetReturnReg(Reg);
513 }
514 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
515 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
516 }
517
518 if (IsVarArg) {
519 // Record the frame index of the first variable argument
520 // which is a value necessary to VASTART.
521 int FI = MFI.CreateFixedObject(4, CCInfo.getStackSize(), true);
522 LanaiMFI->setVarArgsFrameIndex(FI);
523 }
524
525 return Chain;
526}
527
529 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
530 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
531 const Type *RetTy) 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 Glue;
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], Glue);
563
564 // Guarantee that all emitted copies are stuck together with flags.
565 Glue = 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, Glue);
583 Glue = 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_GLUE;
591 if (Glue.getNode())
592 RetOps.push_back(Glue);
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.getStackSize();
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 /*CI=*/nullptr, std::nullopt, 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())
711 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
712 ArrayRef<SDValue>(&MemOpChains[0], MemOpChains.size()));
713
714 SDValue InGlue;
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 InGlue 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, InGlue);
722 InGlue = 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.
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 (InGlue.getNode())
757 Ops.push_back(InGlue);
758
759 Chain = DAG.getNode(LanaiISD::CALL, DL, NodeTys,
760 ArrayRef<SDValue>(&Ops[0], Ops.size()));
761 InGlue = Chain.getValue(1);
762
763 // Create the CALLSEQ_END node.
764 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
765 InGlue = Chain.getValue(1);
766
767 // Handle result values, copying them out of physregs into vregs that we
768 // return.
769 return LowerCallResult(Chain, InGlue, 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 InGlue, 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(), InGlue)
790 .getValue(1);
791 InGlue = 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 Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
878
879 return DAG.getNode(LanaiISD::BR_CC, DL, Op.getValueType(), Chain, Dest,
880 TargetCC, Glue);
881}
882
884 EVT VT = Op->getValueType(0);
885 if (VT != MVT::i32)
886 return SDValue();
887
888 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op->getOperand(1));
889 if (!C)
890 return SDValue();
891
892 int64_t MulAmt = C->getSExtValue();
893 int32_t HighestOne = -1;
894 uint32_t NonzeroEntries = 0;
895 int SignedDigit[32] = {0};
896
897 // Convert to non-adjacent form (NAF) signed-digit representation.
898 // NAF is a signed-digit form where no adjacent digits are non-zero. It is the
899 // minimal Hamming weight representation of a number (on average 1/3 of the
900 // digits will be non-zero vs 1/2 for regular binary representation). And as
901 // the non-zero digits will be the only digits contributing to the instruction
902 // count, this is desirable. The next loop converts it to NAF (following the
903 // approach in 'Guide to Elliptic Curve Cryptography' [ISBN: 038795273X]) by
904 // choosing the non-zero coefficients such that the resulting quotient is
905 // divisible by 2 which will cause the next coefficient to be zero.
906 int64_t E = std::abs(MulAmt);
907 int S = (MulAmt < 0 ? -1 : 1);
908 int I = 0;
909 while (E > 0) {
910 int ZI = 0;
911 if (E % 2 == 1) {
912 ZI = 2 - (E % 4);
913 if (ZI != 0)
914 ++NonzeroEntries;
915 }
916 SignedDigit[I] = S * ZI;
917 if (SignedDigit[I] == 1)
918 HighestOne = I;
919 E = (E - ZI) / 2;
920 ++I;
921 }
922
923 // Compute number of instructions required. Due to differences in lowering
924 // between the different processors this count is not exact.
925 // Start by assuming a shift and a add/sub for every non-zero entry (hence
926 // every non-zero entry requires 1 shift and 1 add/sub except for the first
927 // entry).
928 int32_t InstrRequired = 2 * NonzeroEntries - 1;
929 // Correct possible over-adding due to shift by 0 (which is not emitted).
930 if (std::abs(MulAmt) % 2 == 1)
931 --InstrRequired;
932 // Return if the form generated would exceed the instruction threshold.
933 if (InstrRequired > LanaiLowerConstantMulThreshold)
934 return SDValue();
935
936 SDValue Res;
937 SDLoc DL(Op);
938 SDValue V = Op->getOperand(0);
939
940 // Initialize the running sum. Set the running sum to the maximal shifted
941 // positive value (i.e., largest i such that zi == 1 and MulAmt has V<<i as a
942 // term NAF).
943 if (HighestOne == -1)
944 Res = DAG.getConstant(0, DL, MVT::i32);
945 else {
946 Res = DAG.getNode(ISD::SHL, DL, VT, V,
947 DAG.getConstant(HighestOne, DL, MVT::i32));
948 SignedDigit[HighestOne] = 0;
949 }
950
951 // Assemble multiplication from shift, add, sub using NAF form and running
952 // sum.
953 for (unsigned int I = 0; I < std::size(SignedDigit); ++I) {
954 if (SignedDigit[I] == 0)
955 continue;
956
957 // Shifted multiplicand (v<<i).
958 SDValue Op =
959 DAG.getNode(ISD::SHL, DL, VT, V, DAG.getConstant(I, DL, MVT::i32));
960 if (SignedDigit[I] == 1)
961 Res = DAG.getNode(ISD::ADD, DL, VT, Res, Op);
962 else if (SignedDigit[I] == -1)
963 Res = DAG.getNode(ISD::SUB, DL, VT, Res, Op);
964 }
965 return Res;
966}
967
969 SDValue LHS = Op.getOperand(0);
970 SDValue RHS = Op.getOperand(1);
971 SDValue Cond = Op.getOperand(2);
972 SDLoc DL(Op);
973
975 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
976 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
977
978 return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Glue);
979}
980
982 SelectionDAG &DAG) const {
983 SDValue LHS = Op.getOperand(0);
984 SDValue RHS = Op.getOperand(1);
985 SDValue TrueV = Op.getOperand(2);
986 SDValue FalseV = Op.getOperand(3);
987 SDValue Cond = Op.getOperand(4);
988 SDLoc DL(Op);
989
991 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
992 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
993
994 return DAG.getNode(LanaiISD::SELECT_CC, DL, Op.getValueType(), TrueV, FalseV,
995 TargetCC, Glue);
996}
997
1001
1002 SDLoc DL(Op);
1003 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1005
1006 // vastart just stores the address of the VarArgsFrameIndex slot into the
1007 // memory location argument.
1008 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1009 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1010 MachinePointerInfo(SV));
1011}
1012
1014 SelectionDAG &DAG) const {
1015 SDValue Chain = Op.getOperand(0);
1016 SDValue Size = Op.getOperand(1);
1017 SDLoc DL(Op);
1018
1020
1021 // Get a reference to the stack pointer.
1022 SDValue StackPointer = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1023
1024 // Subtract the dynamic size from the actual stack size to
1025 // obtain the new stack size.
1026 SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i32, StackPointer, Size);
1027
1028 // For Lanai, the outgoing memory arguments area should be on top of the
1029 // alloca area on the stack i.e., the outgoing memory arguments should be
1030 // at a lower address than the alloca area. Move the alloca area down the
1031 // stack by adding back the space reserved for outgoing arguments to SP
1032 // here.
1033 //
1034 // We do not know what the size of the outgoing args is at this point.
1035 // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
1036 // stack pointer. We replace this instruction with on that has the correct,
1037 // known offset in emitPrologue().
1038 SDValue ArgAdjust = DAG.getNode(LanaiISD::ADJDYNALLOC, DL, MVT::i32, Sub);
1039
1040 // The Sub result contains the new stack start address, so it
1041 // must be placed in the stack pointer register.
1042 SDValue CopyChain = DAG.getCopyToReg(Chain, DL, SPReg, Sub);
1043
1044 SDValue Ops[2] = {ArgAdjust, CopyChain};
1045 return DAG.getMergeValues(Ops, DL);
1046}
1047
1049 SelectionDAG &DAG) const {
1051 MachineFrameInfo &MFI = MF.getFrameInfo();
1052 MFI.setReturnAddressIsTaken(true);
1053
1054 EVT VT = Op.getValueType();
1055 SDLoc DL(Op);
1056 unsigned Depth = Op.getConstantOperandVal(0);
1057 if (Depth) {
1058 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1059 const unsigned Offset = -4;
1060 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1062 return DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1063 }
1064
1065 // Return the link register, which contains the return address.
1066 // Mark it an implicit live-in.
1067 Register Reg = MF.addLiveIn(TRI->getRARegister(), getRegClassFor(MVT::i32));
1068 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
1069}
1070
1072 SelectionDAG &DAG) const {
1074 MFI.setFrameAddressIsTaken(true);
1075
1076 EVT VT = Op.getValueType();
1077 SDLoc DL(Op);
1078 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Lanai::FP, VT);
1079 unsigned Depth = Op.getConstantOperandVal(0);
1080 while (Depth--) {
1081 const unsigned Offset = -8;
1082 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1084 FrameAddr =
1085 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1086 }
1087 return FrameAddr;
1088}
1089
1090const char *LanaiTargetLowering::getTargetNodeName(unsigned Opcode) const {
1091 switch (Opcode) {
1093 return "LanaiISD::ADJDYNALLOC";
1094 case LanaiISD::RET_GLUE:
1095 return "LanaiISD::RET_GLUE";
1096 case LanaiISD::CALL:
1097 return "LanaiISD::CALL";
1099 return "LanaiISD::SELECT_CC";
1100 case LanaiISD::SETCC:
1101 return "LanaiISD::SETCC";
1102 case LanaiISD::SUBBF:
1103 return "LanaiISD::SUBBF";
1104 case LanaiISD::SET_FLAG:
1105 return "LanaiISD::SET_FLAG";
1106 case LanaiISD::BR_CC:
1107 return "LanaiISD::BR_CC";
1108 case LanaiISD::Wrapper:
1109 return "LanaiISD::Wrapper";
1110 case LanaiISD::HI:
1111 return "LanaiISD::HI";
1112 case LanaiISD::LO:
1113 return "LanaiISD::LO";
1114 case LanaiISD::SMALL:
1115 return "LanaiISD::SMALL";
1116 default:
1117 return nullptr;
1118 }
1119}
1120
1122 SelectionDAG &DAG) const {
1123 SDLoc DL(Op);
1124 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1125 const Constant *C = N->getConstVal();
1126 const LanaiTargetObjectFile *TLOF =
1127 static_cast<const LanaiTargetObjectFile *>(
1129
1130 // If the code model is small or constant will be placed in the small section,
1131 // then assume address will fit in 21-bits.
1134 SDValue Small = DAG.getTargetConstantPool(
1135 C, MVT::i32, N->getAlign(), N->getOffset(), LanaiII::MO_NO_FLAG);
1136 return DAG.getNode(ISD::OR, DL, MVT::i32,
1137 DAG.getRegister(Lanai::R0, MVT::i32),
1138 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1139 } else {
1140 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1141 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1142
1143 SDValue Hi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1144 N->getOffset(), OpFlagHi);
1145 SDValue Lo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1146 N->getOffset(), OpFlagLo);
1147 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1148 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1149 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1150 return Result;
1151 }
1152}
1153
1155 SelectionDAG &DAG) const {
1156 SDLoc DL(Op);
1157 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1158 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1159
1160 const LanaiTargetObjectFile *TLOF =
1161 static_cast<const LanaiTargetObjectFile *>(
1163
1164 // If the code model is small or global variable will be placed in the small
1165 // section, then assume address will fit in 21-bits.
1166 const GlobalObject *GO = GV->getAliaseeObject();
1167 if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
1168 SDValue Small = DAG.getTargetGlobalAddress(
1170 return DAG.getNode(ISD::OR, DL, MVT::i32,
1171 DAG.getRegister(Lanai::R0, MVT::i32),
1172 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1173 } else {
1174 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1175 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1176
1177 // Create the TargetGlobalAddress node, folding in the constant offset.
1179 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagHi);
1181 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagLo);
1182 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1183 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1184 return DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1185 }
1186}
1187
1189 SelectionDAG &DAG) const {
1190 SDLoc DL(Op);
1191 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1192
1193 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1194 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1195
1196 SDValue Hi = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagHi);
1197 SDValue Lo = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagLo);
1198 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1199 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1200 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1201 return Result;
1202}
1203
1205 SelectionDAG &DAG) const {
1206 SDLoc DL(Op);
1207 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1208
1209 // If the code model is small assume address will fit in 21-bits.
1211 SDValue Small = DAG.getTargetJumpTable(
1212 JT->getIndex(), getPointerTy(DAG.getDataLayout()), LanaiII::MO_NO_FLAG);
1213 return DAG.getNode(ISD::OR, DL, MVT::i32,
1214 DAG.getRegister(Lanai::R0, MVT::i32),
1215 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1216 } else {
1217 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1218 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1219
1221 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagHi);
1223 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagLo);
1224 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1225 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1226 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1227 return Result;
1228 }
1229}
1230
1232 SelectionDAG &DAG) const {
1233 EVT VT = Op.getValueType();
1234 unsigned VTBits = VT.getSizeInBits();
1235 SDLoc dl(Op);
1236 assert(Op.getNumOperands() == 3 && "Unexpected SHL!");
1237 SDValue ShOpLo = Op.getOperand(0);
1238 SDValue ShOpHi = Op.getOperand(1);
1239 SDValue ShAmt = Op.getOperand(2);
1240
1241 // Performs the following for (ShOpLo + (ShOpHi << 32)) << ShAmt:
1242 // LoBitsForHi = (ShAmt == 0) ? 0 : (ShOpLo >> (32-ShAmt))
1243 // HiBitsForHi = ShOpHi << ShAmt
1244 // Hi = (ShAmt >= 32) ? (ShOpLo << (ShAmt-32)) : (LoBitsForHi | HiBitsForHi)
1245 // Lo = (ShAmt >= 32) ? 0 : (ShOpLo << ShAmt)
1246 // return (Hi << 32) | Lo;
1247
1248 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
1249 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1250 SDValue LoBitsForHi = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
1251
1252 // If ShAmt == 0, we just calculated "(SRL ShOpLo, 32)" which is "undef". We
1253 // wanted 0, so CSEL it directly.
1254 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1255 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1256 LoBitsForHi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, LoBitsForHi);
1257
1258 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
1259 DAG.getConstant(VTBits, dl, MVT::i32));
1260 SDValue HiBitsForHi = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
1261 SDValue HiForNormalShift =
1262 DAG.getNode(ISD::OR, dl, VT, LoBitsForHi, HiBitsForHi);
1263
1264 SDValue HiForBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
1265
1266 SetCC = DAG.getSetCC(dl, MVT::i32, ExtraShAmt, Zero, ISD::SETGE);
1267 SDValue Hi =
1268 DAG.getSelect(dl, MVT::i32, SetCC, HiForBigShift, HiForNormalShift);
1269
1270 // Lanai shifts of larger than register sizes are wrapped rather than
1271 // clamped, so we can't just emit "lo << b" if b is too big.
1272 SDValue LoForNormalShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
1273 SDValue Lo = DAG.getSelect(
1274 dl, MVT::i32, SetCC, DAG.getConstant(0, dl, MVT::i32), LoForNormalShift);
1275
1276 SDValue Ops[2] = {Lo, Hi};
1277 return DAG.getMergeValues(Ops, dl);
1278}
1279
1281 SelectionDAG &DAG) const {
1282 MVT VT = Op.getSimpleValueType();
1283 unsigned VTBits = VT.getSizeInBits();
1284 SDLoc dl(Op);
1285 SDValue ShOpLo = Op.getOperand(0);
1286 SDValue ShOpHi = Op.getOperand(1);
1287 SDValue ShAmt = Op.getOperand(2);
1288
1289 // Performs the following for a >> b:
1290 // unsigned r_high = a_high >> b;
1291 // r_high = (32 - b <= 0) ? 0 : r_high;
1292 //
1293 // unsigned r_low = a_low >> b;
1294 // r_low = (32 - b <= 0) ? r_high : r_low;
1295 // r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
1296 // return (unsigned long long)r_high << 32 | r_low;
1297 // Note: This takes advantage of Lanai's shift behavior to avoid needing to
1298 // mask the shift amount.
1299
1300 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1301 SDValue NegatedPlus32 = DAG.getNode(
1302 ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1303 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
1304
1305 SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
1306 Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
1307
1308 SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
1309 Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
1310 SDValue CarryBits =
1311 DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
1312 SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1313 Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
1314 DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
1315
1316 SDValue Ops[2] = {Lo, Hi};
1317 return DAG.getMergeValues(Ops, dl);
1318}
1319
1320// Helper function that checks if N is a null or all ones constant.
1321static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
1323}
1324
1325// Return true if N is conditionally 0 or all ones.
1326// Detects these expressions where cc is an i1 value:
1327//
1328// (select cc 0, y) [AllOnes=0]
1329// (select cc y, 0) [AllOnes=0]
1330// (zext cc) [AllOnes=0]
1331// (sext cc) [AllOnes=0/1]
1332// (select cc -1, y) [AllOnes=1]
1333// (select cc y, -1) [AllOnes=1]
1334//
1335// * AllOnes determines whether to check for an all zero (AllOnes false) or an
1336// all ones operand (AllOnes true).
1337// * Invert is set when N is the all zero/ones constant when CC is false.
1338// * OtherOp is set to the alternative value of N.
1339//
1340// For example, for (select cc X, Y) and AllOnes = 0 if:
1341// * X = 0, Invert = False and OtherOp = Y
1342// * Y = 0, Invert = True and OtherOp = X
1344 bool &Invert, SDValue &OtherOp,
1345 SelectionDAG &DAG) {
1346 switch (N->getOpcode()) {
1347 default:
1348 return false;
1349 case ISD::SELECT: {
1350 CC = N->getOperand(0);
1351 SDValue N1 = N->getOperand(1);
1352 SDValue N2 = N->getOperand(2);
1353 if (isZeroOrAllOnes(N1, AllOnes)) {
1354 Invert = false;
1355 OtherOp = N2;
1356 return true;
1357 }
1358 if (isZeroOrAllOnes(N2, AllOnes)) {
1359 Invert = true;
1360 OtherOp = N1;
1361 return true;
1362 }
1363 return false;
1364 }
1365 case ISD::ZERO_EXTEND: {
1366 // (zext cc) can never be the all ones value.
1367 if (AllOnes)
1368 return false;
1369 CC = N->getOperand(0);
1370 if (CC.getValueType() != MVT::i1)
1371 return false;
1372 SDLoc dl(N);
1373 EVT VT = N->getValueType(0);
1374 OtherOp = DAG.getConstant(1, dl, VT);
1375 Invert = true;
1376 return true;
1377 }
1378 case ISD::SIGN_EXTEND: {
1379 CC = N->getOperand(0);
1380 if (CC.getValueType() != MVT::i1)
1381 return false;
1382 SDLoc dl(N);
1383 EVT VT = N->getValueType(0);
1384 Invert = !AllOnes;
1385 if (AllOnes)
1386 // When looking for an AllOnes constant, N is an sext, and the 'other'
1387 // value is 0.
1388 OtherOp = DAG.getConstant(0, dl, VT);
1389 else
1390 OtherOp = DAG.getAllOnesConstant(dl, VT);
1391 return true;
1392 }
1393 }
1394}
1395
1396// Combine a constant select operand into its use:
1397//
1398// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
1399// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1400// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
1401// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
1402// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
1403//
1404// The transform is rejected if the select doesn't have a constant operand that
1405// is null, or all ones when AllOnes is set.
1406//
1407// Also recognize sext/zext from i1:
1408//
1409// (add (zext cc), x) -> (select cc (add x, 1), x)
1410// (add (sext cc), x) -> (select cc (add x, -1), x)
1411//
1412// These transformations eventually create predicated instructions.
1415 bool AllOnes) {
1416 SelectionDAG &DAG = DCI.DAG;
1417 EVT VT = N->getValueType(0);
1418 SDValue NonConstantVal;
1419 SDValue CCOp;
1420 bool SwapSelectOps;
1421 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
1422 NonConstantVal, DAG))
1423 return SDValue();
1424
1425 // Slct is now know to be the desired identity constant when CC is true.
1426 SDValue TrueVal = OtherOp;
1427 SDValue FalseVal =
1428 DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
1429 // Unless SwapSelectOps says CC should be false.
1430 if (SwapSelectOps)
1431 std::swap(TrueVal, FalseVal);
1432
1433 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
1434}
1435
1436// Attempt combineSelectAndUse on each operand of a commutative operator N.
1437static SDValue
1439 bool AllOnes) {
1440 SDValue N0 = N->getOperand(0);
1441 SDValue N1 = N->getOperand(1);
1442 if (N0.getNode()->hasOneUse())
1443 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
1444 return Result;
1445 if (N1.getNode()->hasOneUse())
1446 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
1447 return Result;
1448 return SDValue();
1449}
1450
1451// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
1454 SDValue N0 = N->getOperand(0);
1455 SDValue N1 = N->getOperand(1);
1456
1457 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1458 if (N1.getNode()->hasOneUse())
1459 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
1460 return Result;
1461
1462 return SDValue();
1463}
1464
1466 DAGCombinerInfo &DCI) const {
1467 switch (N->getOpcode()) {
1468 default:
1469 break;
1470 case ISD::ADD:
1471 case ISD::OR:
1472 case ISD::XOR:
1473 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
1474 case ISD::AND:
1475 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
1476 case ISD::SUB:
1477 return PerformSUBCombine(N, DCI);
1478 }
1479
1480 return SDValue();
1481}
1482
1484 const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
1485 const SelectionDAG &DAG, unsigned Depth) const {
1486 unsigned BitWidth = Known.getBitWidth();
1487 switch (Op.getOpcode()) {
1488 default:
1489 break;
1490 case LanaiISD::SETCC:
1491 Known = KnownBits(BitWidth);
1492 Known.Zero.setBits(1, BitWidth);
1493 break;
1495 KnownBits Known2;
1496 Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
1497 Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
1498 Known = Known.intersectWith(Known2);
1499 break;
1500 }
1501}
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)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
return RetTy
#define LLVM_DEBUG(...)
Definition: Debug.h:106
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
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static constexpr Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
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:78
void setBits(unsigned loBit, unsigned hiBit)
Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
Definition: APInt.h:1367
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:893
CCState - This class holds information needed while lowering arguments and return values.
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 ...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
bool isMemLoc() const
int64_t getLocMemOffset() const
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:216
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:688
const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:400
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)
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 Type *RetTy) 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.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
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:228
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:750
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:801
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 getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
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 getRegister(Register Reg, EVT VT)
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:760
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 getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
Definition: SelectionDAG.h:827
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:497
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
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 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:700
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:492
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:510
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:767
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:580
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
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.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
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 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.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
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...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
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:125
@ 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:780
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1197
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1193
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:744
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1226
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:814
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:805
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1148
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1127
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:757
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1222
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:674
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:735
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:811
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1112
@ 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:849
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:709
@ 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:817
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1217
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1141
@ 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:794
@ 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:1610
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:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
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:167
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:217
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:860
#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:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
unsigned getBitWidth() const
Get the bit width of this value.
Definition: KnownBits.h:43
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition: KnownBits.h:303
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