|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | #include "RISCVLegalizerInfo.h"
|
| 14 | +#include "MCTargetDesc/RISCVMatInt.h" |
14 | 15 | #include "RISCVMachineFunctionInfo.h"
|
15 | 16 | #include "RISCVSubtarget.h"
|
| 17 | +#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" |
16 | 18 | #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
|
17 | 19 | #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
|
18 | 20 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
| 21 | +#include "llvm/CodeGen/MachineConstantPool.h" |
19 | 22 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
20 | 23 | #include "llvm/CodeGen/TargetOpcodes.h"
|
21 | 24 | #include "llvm/CodeGen/ValueTypes.h"
|
@@ -182,7 +185,13 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
182 | 185 | CTPOPActions.maxScalar(0, sXLen).scalarSameSizeAs(1, 0).lower();
|
183 | 186 | }
|
184 | 187 |
|
185 |
| - getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF}) |
| 188 | + auto &ConstantActions = getActionDefinitionsBuilder(G_CONSTANT); |
| 189 | + ConstantActions.legalFor({s32, p0}); |
| 190 | + if (ST.is64Bit()) |
| 191 | + ConstantActions.customFor({s64}); |
| 192 | + ConstantActions.widenScalarToNextPow2(0).clampScalar(0, s32, sXLen); |
| 193 | + |
| 194 | + getActionDefinitionsBuilder(G_IMPLICIT_DEF) |
186 | 195 | .legalFor({s32, sXLen, p0})
|
187 | 196 | .widenScalarToNextPow2(0)
|
188 | 197 | .clampScalar(0, s32, sXLen);
|
@@ -451,17 +460,95 @@ bool RISCVLegalizerInfo::legalizeVAStart(MachineInstr &MI,
|
451 | 460 | return true;
|
452 | 461 | }
|
453 | 462 |
|
| 463 | +bool RISCVLegalizerInfo::shouldBeInConstantPool(APInt APImm, |
| 464 | + bool ShouldOptForSize) const { |
| 465 | + unsigned BitWidth = APImm.getBitWidth(); |
| 466 | + assert(BitWidth == 32 || BitWidth == 64); |
| 467 | + int64_t Imm = APImm.getSExtValue(); |
| 468 | + // All simm32 constants should be handled by isel. |
| 469 | + // NOTE: The getMaxBuildIntsCost call below should return a value >= 2 making |
| 470 | + // this check redundant, but small immediates are common so this check |
| 471 | + // should have better compile time. |
| 472 | + if (isInt<32>(Imm)) |
| 473 | + return false; |
| 474 | + |
| 475 | + // We only need to cost the immediate, if constant pool lowering is enabled. |
| 476 | + if (!STI.useConstantPoolForLargeInts()) |
| 477 | + return false; |
| 478 | + |
| 479 | + RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Imm, STI); |
| 480 | + if (Seq.size() <= STI.getMaxBuildIntsCost()) |
| 481 | + return false; |
| 482 | + |
| 483 | + // Optimizations below are disabled for opt size. If we're optimizing for |
| 484 | + // size, use a constant pool. |
| 485 | + if (ShouldOptForSize) |
| 486 | + return true; |
| 487 | + // |
| 488 | + // Special case. See if we can build the constant as (ADD (SLLI X, C), X) do |
| 489 | + // that if it will avoid a constant pool. |
| 490 | + // It will require an extra temporary register though. |
| 491 | + // If we have Zba we can use (ADD_UW X, (SLLI X, 32)) to handle cases where |
| 492 | + // low and high 32 bits are the same and bit 31 and 63 are set. |
| 493 | + unsigned ShiftAmt, AddOpc; |
| 494 | + RISCVMatInt::InstSeq SeqLo = |
| 495 | + RISCVMatInt::generateTwoRegInstSeq(Imm, STI, ShiftAmt, AddOpc); |
| 496 | + return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost()); |
| 497 | +} |
| 498 | + |
| 499 | +// TODO: This is almost the same as LegalizerHelper::lowerFConstant and is |
| 500 | +// target-independent. Should we move this to LegalizeHelper? |
| 501 | +bool RISCVLegalizerInfo::emitLoadFromConstantPool( |
| 502 | + Register DstReg, const Constant *ConstVal, |
| 503 | + MachineIRBuilder &MIRBuilder) const { |
| 504 | + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); |
| 505 | + MachineFunction &MF = MIRBuilder.getMF(); |
| 506 | + const DataLayout &DL = MIRBuilder.getDataLayout(); |
| 507 | + LLVMContext &Ctx = MF.getFunction().getContext(); |
| 508 | + unsigned AddrSpace = DL.getDefaultGlobalsAddressSpace(); |
| 509 | + LLT AddrPtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace)); |
| 510 | + LLT DstLLT = MRI.getType(DstReg); |
| 511 | + |
| 512 | + Align Alignment(DL.getABITypeAlign(getTypeForLLT(DstLLT, Ctx))); |
| 513 | + |
| 514 | + auto Addr = MIRBuilder.buildConstantPool( |
| 515 | + AddrPtrTy, |
| 516 | + MF.getConstantPool()->getConstantPoolIndex(ConstVal, Alignment)); |
| 517 | + |
| 518 | + MachineMemOperand *MMO = |
| 519 | + MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), |
| 520 | + MachineMemOperand::MOLoad, DstLLT, Alignment); |
| 521 | + |
| 522 | + MIRBuilder.buildLoadInstr(TargetOpcode::G_LOAD, DstReg, Addr, *MMO); |
| 523 | + return true; |
| 524 | +} |
| 525 | + |
454 | 526 | bool RISCVLegalizerInfo::legalizeCustom(
|
455 | 527 | LegalizerHelper &Helper, MachineInstr &MI,
|
456 | 528 | LostDebugLocObserver &LocObserver) const {
|
457 | 529 | MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
|
458 | 530 | GISelChangeObserver &Observer = Helper.Observer;
|
| 531 | + MachineFunction &MF = *MI.getParent()->getParent(); |
459 | 532 | switch (MI.getOpcode()) {
|
460 | 533 | default:
|
461 | 534 | // No idea what to do.
|
462 | 535 | return false;
|
463 | 536 | case TargetOpcode::G_ABS:
|
464 | 537 | return Helper.lowerAbsToMaxNeg(MI);
|
| 538 | + // TODO: G_FCONSTANT |
| 539 | + case TargetOpcode::G_CONSTANT: { |
| 540 | + const Function &F = MF.getFunction(); |
| 541 | + // TODO: if PSI and BFI are present, add " || |
| 542 | + // llvm::shouldOptForSize(*CurMBB, PSI, BFI)". |
| 543 | + bool ShouldOptForSize = F.hasOptSize() || F.hasMinSize(); |
| 544 | + const ConstantInt *ConstVal = MI.getOperand(1).getCImm(); |
| 545 | + if (!shouldBeInConstantPool(ConstVal->getValue(), ShouldOptForSize)) |
| 546 | + return true; |
| 547 | + emitLoadFromConstantPool(MI.getOperand(0).getReg(), |
| 548 | + MI.getOperand(1).getCImm(), MIRBuilder); |
| 549 | + MI.eraseFromParent(); |
| 550 | + return true; |
| 551 | + } |
465 | 552 | case TargetOpcode::G_SHL:
|
466 | 553 | case TargetOpcode::G_ASHR:
|
467 | 554 | case TargetOpcode::G_LSHR:
|
|
0 commit comments