42 #include "llvm/Config/llvm-config.h" 52 #define DEBUG_TYPE "x86-codegen" 54 STATISTIC(NumFXCH,
"Number of fxch instructions inserted");
55 STATISTIC(NumFP ,
"Number of floating point instructions");
58 const unsigned ScratchFPReg = 7;
66 memset(Stack, 0,
sizeof(Stack));
67 memset(RegMap, 0,
sizeof(RegMap));
85 StringRef getPassName()
const override {
return "X86 FP Stackifier"; }
111 unsigned char FixStack[8];
113 LiveBundle() : Mask(0), FixCount(0) {}
116 bool isFixed()
const {
return !Mask || FixCount; }
132 static_assert(X86::FP6 - X86::FP0 == 6,
"sequential regnums");
133 if (Reg >= X86::FP0 && Reg <= X86::FP6) {
134 Mask |= 1 << (Reg - X86::FP0);
165 unsigned RegMap[NumFPRegs];
168 void setupBlockStack();
171 void finishBlockStack();
173 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 174 void dumpStack()
const {
175 dbgs() <<
"Stack contents:";
176 for (
unsigned i = 0; i != StackTop; ++i) {
177 dbgs() <<
" FP" << Stack[i];
178 assert(RegMap[Stack[i]] == i &&
"Stack[] doesn't match RegMap[]!");
185 unsigned getSlot(
unsigned RegNo)
const {
186 assert(RegNo < NumFPRegs &&
"Regno out of range!");
187 return RegMap[RegNo];
191 bool isLive(
unsigned RegNo)
const {
192 unsigned Slot = getSlot(RegNo);
193 return Slot < StackTop && Stack[Slot] == RegNo;
197 unsigned getStackEntry(
unsigned STi)
const {
200 return Stack[StackTop-1-STi];
205 unsigned getSTReg(
unsigned RegNo)
const {
206 return StackTop - 1 - getSlot(RegNo) + X86::ST0;
210 void pushReg(
unsigned Reg) {
211 assert(Reg < NumFPRegs &&
"Register number out of range!");
214 Stack[StackTop] =
Reg;
215 RegMap[
Reg] = StackTop++;
222 RegMap[Stack[--StackTop]] = ~0;
225 bool isAtTop(
unsigned RegNo)
const {
return getSlot(RegNo) == StackTop-1; }
228 if (isAtTop(RegNo))
return;
230 unsigned STReg = getSTReg(RegNo);
231 unsigned RegOnTop = getStackEntry(0);
234 std::swap(RegMap[RegNo], RegMap[RegOnTop]);
237 if (RegMap[RegOnTop] >= StackTop)
239 std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
242 BuildMI(*MBB, I, dl, TII->
get(X86::XCH_F)).addReg(STReg);
246 void duplicateToTop(
unsigned RegNo,
unsigned AsReg,
249 unsigned STReg = getSTReg(RegNo);
252 BuildMI(*MBB, I, dl, TII->
get(X86::LD_Frr)).addReg(STReg);
276 void shuffleStackTop(
const unsigned char *FixStack,
unsigned FixCount,
296 return X86::RFP80RegClass.contains(DstReg) ||
297 X86::RFP80RegClass.contains(SrcReg);
311 unsigned Reg = MO.
getReg();
312 assert(Reg >= X86::FP0 && Reg <= X86::FP6 &&
"Expected FP register!");
313 return Reg - X86::FP0;
322 bool FPIsUsed =
false;
324 static_assert(X86::FP6 == X86::FP0+6,
"Register enums aren't sorted right!");
326 for (
unsigned i = 0; i <= 6; ++i)
333 if (!FPIsUsed)
return false;
335 Bundles = &getAnalysis<EdgeBundles>();
339 bundleCFGRecomputeKillFlags(MF);
361 assert((Bundle.Mask & 0xFE) == 0 &&
362 "Only FP0 could be passed as an argument");
364 Bundle.FixStack[0] = 0;
367 bool Changed =
false;
369 Changed |= processBasicBlock(MF, *BB);
374 if (Processed.
insert(&BB).second)
375 Changed |= processBasicBlock(MF, BB);
388 assert(LiveBundles.
empty() &&
"Stale data in LiveBundles");
395 const unsigned Mask = calcLiveInMask(&MBB,
false);
407 bool Changed =
false;
420 if (MI.
isCopy() && isFPCopy(MI))
435 PrevMI = &*std::prev(I);
449 switch (FPInstClass) {
462 for (
unsigned i = 0, e = DeadRegs.
size(); i != e; ++i) {
463 unsigned Reg = DeadRegs[i];
466 static_assert(X86::FP7 - X86::FP0 == 7,
"sequential FP regnumbers");
467 if (Reg >= X86::FP0 && Reg <= X86::FP6 && isLive(Reg-X86::FP0)) {
468 LLVM_DEBUG(
dbgs() <<
"Register FP#" << Reg - X86::FP0 <<
" is dead!\n");
469 freeStackSlotAfter(I, Reg-X86::FP0);
477 dbgs() <<
"Just deleted pseudo instruction\n";
481 while (Start != BB.
begin() && std::prev(Start) != PrevI)
483 dbgs() <<
"Inserted instructions:\n\t";
484 Start->print(
dbgs());
485 while (++Start != std::next(I)) {
502 void FPS::setupBlockStack() {
504 <<
" derived from " << MBB->
getName() <<
".\n");
507 const LiveBundle &Bundle =
516 assert(Bundle.isFixed() &&
"Reached block before any predecessors");
519 for (
unsigned i = Bundle.FixCount; i > 0; --i) {
521 <<
unsigned(Bundle.FixStack[i - 1]) <<
'\n');
522 pushReg(Bundle.FixStack[i-1]);
528 unsigned Mask = calcLiveInMask(MBB,
true);
529 adjustLiveRegs(Mask, MBB->
begin());
537 void FPS::finishBlockStack() {
543 <<
" derived from " << MBB->
getName() <<
".\n");
547 LiveBundle &Bundle = LiveBundles[BundleIdx];
552 adjustLiveRegs(Bundle.Mask, Term);
561 if (Bundle.isFixed()) {
563 shuffleStackTop(Bundle.FixStack, Bundle.FixCount, Term);
567 Bundle.FixCount = StackTop;
568 for (
unsigned i = 0; i < StackTop; ++i)
569 Bundle.FixStack[i] = getStackEntry(i);
582 bool operator<(
const TableEntry &TE)
const {
return from < TE.from; }
583 friend bool operator<(
const TableEntry &TE,
unsigned V) {
587 const TableEntry &TE) {
595 if (I != Table.
end() && I->from == Opcode)
601 #define ASSERT_SORTED(TABLE) 603 #define ASSERT_SORTED(TABLE) \ 605 static std::atomic<bool> TABLE##Checked(false); \ 606 if (!TABLE##Checked.load(std::memory_order_relaxed)) { \ 607 assert(std::is_sorted(std::begin(TABLE), std::end(TABLE)) && \ 608 "All lookup tables must be sorted for efficient access!"); \ 609 TABLE##Checked.store(true, std::memory_order_relaxed); \ 623 { X86::ABS_Fp32 , X86::ABS_F },
624 { X86::ABS_Fp64 , X86::ABS_F },
625 { X86::ABS_Fp80 , X86::ABS_F },
626 { X86::ADD_Fp32m , X86::ADD_F32m },
627 { X86::ADD_Fp64m , X86::ADD_F64m },
628 { X86::ADD_Fp64m32 , X86::ADD_F32m },
629 { X86::ADD_Fp80m32 , X86::ADD_F32m },
630 { X86::ADD_Fp80m64 , X86::ADD_F64m },
631 { X86::ADD_FpI16m32 , X86::ADD_FI16m },
632 { X86::ADD_FpI16m64 , X86::ADD_FI16m },
633 { X86::ADD_FpI16m80 , X86::ADD_FI16m },
634 { X86::ADD_FpI32m32 , X86::ADD_FI32m },
635 { X86::ADD_FpI32m64 , X86::ADD_FI32m },
636 { X86::ADD_FpI32m80 , X86::ADD_FI32m },
637 { X86::CHS_Fp32 , X86::CHS_F },
638 { X86::CHS_Fp64 , X86::CHS_F },
639 { X86::CHS_Fp80 , X86::CHS_F },
640 { X86::CMOVBE_Fp32 , X86::CMOVBE_F },
641 { X86::CMOVBE_Fp64 , X86::CMOVBE_F },
642 { X86::CMOVBE_Fp80 , X86::CMOVBE_F },
643 { X86::CMOVB_Fp32 , X86::CMOVB_F },
644 { X86::CMOVB_Fp64 , X86::CMOVB_F },
645 { X86::CMOVB_Fp80 , X86::CMOVB_F },
646 { X86::CMOVE_Fp32 , X86::CMOVE_F },
647 { X86::CMOVE_Fp64 , X86::CMOVE_F },
648 { X86::CMOVE_Fp80 , X86::CMOVE_F },
649 { X86::CMOVNBE_Fp32 , X86::CMOVNBE_F },
650 { X86::CMOVNBE_Fp64 , X86::CMOVNBE_F },
651 { X86::CMOVNBE_Fp80 , X86::CMOVNBE_F },
652 { X86::CMOVNB_Fp32 , X86::CMOVNB_F },
653 { X86::CMOVNB_Fp64 , X86::CMOVNB_F },
654 { X86::CMOVNB_Fp80 , X86::CMOVNB_F },
655 { X86::CMOVNE_Fp32 , X86::CMOVNE_F },
656 { X86::CMOVNE_Fp64 , X86::CMOVNE_F },
657 { X86::CMOVNE_Fp80 , X86::CMOVNE_F },
658 { X86::CMOVNP_Fp32 , X86::CMOVNP_F },
659 { X86::CMOVNP_Fp64 , X86::CMOVNP_F },
660 { X86::CMOVNP_Fp80 , X86::CMOVNP_F },
661 { X86::CMOVP_Fp32 , X86::CMOVP_F },
662 { X86::CMOVP_Fp64 , X86::CMOVP_F },
663 { X86::CMOVP_Fp80 , X86::CMOVP_F },
664 { X86::COS_Fp32 , X86::COS_F },
665 { X86::COS_Fp64 , X86::COS_F },
666 { X86::COS_Fp80 , X86::COS_F },
667 { X86::DIVR_Fp32m , X86::DIVR_F32m },
668 { X86::DIVR_Fp64m , X86::DIVR_F64m },
669 { X86::DIVR_Fp64m32 , X86::DIVR_F32m },
670 { X86::DIVR_Fp80m32 , X86::DIVR_F32m },
671 { X86::DIVR_Fp80m64 , X86::DIVR_F64m },
672 { X86::DIVR_FpI16m32, X86::DIVR_FI16m},
673 { X86::DIVR_FpI16m64, X86::DIVR_FI16m},
674 { X86::DIVR_FpI16m80, X86::DIVR_FI16m},
675 { X86::DIVR_FpI32m32, X86::DIVR_FI32m},
676 { X86::DIVR_FpI32m64, X86::DIVR_FI32m},
677 { X86::DIVR_FpI32m80, X86::DIVR_FI32m},
678 { X86::DIV_Fp32m , X86::DIV_F32m },
679 { X86::DIV_Fp64m , X86::DIV_F64m },
680 { X86::DIV_Fp64m32 , X86::DIV_F32m },
681 { X86::DIV_Fp80m32 , X86::DIV_F32m },
682 { X86::DIV_Fp80m64 , X86::DIV_F64m },
683 { X86::DIV_FpI16m32 , X86::DIV_FI16m },
684 { X86::DIV_FpI16m64 , X86::DIV_FI16m },
685 { X86::DIV_FpI16m80 , X86::DIV_FI16m },
686 { X86::DIV_FpI32m32 , X86::DIV_FI32m },
687 { X86::DIV_FpI32m64 , X86::DIV_FI32m },
688 { X86::DIV_FpI32m80 , X86::DIV_FI32m },
689 { X86::ILD_Fp16m32 , X86::ILD_F16m },
690 { X86::ILD_Fp16m64 , X86::ILD_F16m },
691 { X86::ILD_Fp16m80 , X86::ILD_F16m },
692 { X86::ILD_Fp32m32 , X86::ILD_F32m },
693 { X86::ILD_Fp32m64 , X86::ILD_F32m },
694 { X86::ILD_Fp32m80 , X86::ILD_F32m },
695 { X86::ILD_Fp64m32 , X86::ILD_F64m },
696 { X86::ILD_Fp64m64 , X86::ILD_F64m },
697 { X86::ILD_Fp64m80 , X86::ILD_F64m },
698 { X86::ISTT_Fp16m32 , X86::ISTT_FP16m},
699 { X86::ISTT_Fp16m64 , X86::ISTT_FP16m},
700 { X86::ISTT_Fp16m80 , X86::ISTT_FP16m},
701 { X86::ISTT_Fp32m32 , X86::ISTT_FP32m},
702 { X86::ISTT_Fp32m64 , X86::ISTT_FP32m},
703 { X86::ISTT_Fp32m80 , X86::ISTT_FP32m},
704 { X86::ISTT_Fp64m32 , X86::ISTT_FP64m},
705 { X86::ISTT_Fp64m64 , X86::ISTT_FP64m},
706 { X86::ISTT_Fp64m80 , X86::ISTT_FP64m},
707 { X86::IST_Fp16m32 , X86::IST_F16m },
708 { X86::IST_Fp16m64 , X86::IST_F16m },
709 { X86::IST_Fp16m80 , X86::IST_F16m },
710 { X86::IST_Fp32m32 , X86::IST_F32m },
711 { X86::IST_Fp32m64 , X86::IST_F32m },
712 { X86::IST_Fp32m80 , X86::IST_F32m },
713 { X86::IST_Fp64m32 , X86::IST_FP64m },
714 { X86::IST_Fp64m64 , X86::IST_FP64m },
715 { X86::IST_Fp64m80 , X86::IST_FP64m },
716 { X86::LD_Fp032 , X86::LD_F0 },
717 { X86::LD_Fp064 , X86::LD_F0 },
718 { X86::LD_Fp080 , X86::LD_F0 },
719 { X86::LD_Fp132 , X86::LD_F1 },
720 { X86::LD_Fp164 , X86::LD_F1 },
721 { X86::LD_Fp180 , X86::LD_F1 },
722 { X86::LD_Fp32m , X86::LD_F32m },
723 { X86::LD_Fp32m64 , X86::LD_F32m },
724 { X86::LD_Fp32m80 , X86::LD_F32m },
725 { X86::LD_Fp64m , X86::LD_F64m },
726 { X86::LD_Fp64m80 , X86::LD_F64m },
727 { X86::LD_Fp80m , X86::LD_F80m },
728 { X86::MUL_Fp32m , X86::MUL_F32m },
729 { X86::MUL_Fp64m , X86::MUL_F64m },
730 { X86::MUL_Fp64m32 , X86::MUL_F32m },
731 { X86::MUL_Fp80m32 , X86::MUL_F32m },
732 { X86::MUL_Fp80m64 , X86::MUL_F64m },
733 { X86::MUL_FpI16m32 , X86::MUL_FI16m },
734 { X86::MUL_FpI16m64 , X86::MUL_FI16m },
735 { X86::MUL_FpI16m80 , X86::MUL_FI16m },
736 { X86::MUL_FpI32m32 , X86::MUL_FI32m },
737 { X86::MUL_FpI32m64 , X86::MUL_FI32m },
738 { X86::MUL_FpI32m80 , X86::MUL_FI32m },
739 { X86::SIN_Fp32 , X86::SIN_F },
740 { X86::SIN_Fp64 , X86::SIN_F },
741 { X86::SIN_Fp80 , X86::SIN_F },
742 { X86::SQRT_Fp32 , X86::SQRT_F },
743 { X86::SQRT_Fp64 , X86::SQRT_F },
744 { X86::SQRT_Fp80 , X86::SQRT_F },
745 { X86::ST_Fp32m , X86::ST_F32m },
746 { X86::ST_Fp64m , X86::ST_F64m },
747 { X86::ST_Fp64m32 , X86::ST_F32m },
748 { X86::ST_Fp80m32 , X86::ST_F32m },
749 { X86::ST_Fp80m64 , X86::ST_F64m },
750 { X86::ST_FpP80m , X86::ST_FP80m },
751 { X86::SUBR_Fp32m , X86::SUBR_F32m },
752 { X86::SUBR_Fp64m , X86::SUBR_F64m },
753 { X86::SUBR_Fp64m32 , X86::SUBR_F32m },
754 { X86::SUBR_Fp80m32 , X86::SUBR_F32m },
755 { X86::SUBR_Fp80m64 , X86::SUBR_F64m },
756 { X86::SUBR_FpI16m32, X86::SUBR_FI16m},
757 { X86::SUBR_FpI16m64, X86::SUBR_FI16m},
758 { X86::SUBR_FpI16m80, X86::SUBR_FI16m},
759 { X86::SUBR_FpI32m32, X86::SUBR_FI32m},
760 { X86::SUBR_FpI32m64, X86::SUBR_FI32m},
761 { X86::SUBR_FpI32m80, X86::SUBR_FI32m},
762 { X86::SUB_Fp32m , X86::SUB_F32m },
763 { X86::SUB_Fp64m , X86::SUB_F64m },
764 { X86::SUB_Fp64m32 , X86::SUB_F32m },
765 { X86::SUB_Fp80m32 , X86::SUB_F32m },
766 { X86::SUB_Fp80m64 , X86::SUB_F64m },
767 { X86::SUB_FpI16m32 , X86::SUB_FI16m },
768 { X86::SUB_FpI16m64 , X86::SUB_FI16m },
769 { X86::SUB_FpI16m80 , X86::SUB_FI16m },
770 { X86::SUB_FpI32m32 , X86::SUB_FI32m },
771 { X86::SUB_FpI32m64 , X86::SUB_FI32m },
772 { X86::SUB_FpI32m80 , X86::SUB_FI32m },
773 { X86::TST_Fp32 , X86::TST_F },
774 { X86::TST_Fp64 , X86::TST_F },
775 { X86::TST_Fp80 , X86::TST_F },
776 { X86::UCOM_FpIr32 , X86::UCOM_FIr },
777 { X86::UCOM_FpIr64 , X86::UCOM_FIr },
778 { X86::UCOM_FpIr80 , X86::UCOM_FIr },
779 { X86::UCOM_Fpr32 , X86::UCOM_Fr },
780 { X86::UCOM_Fpr64 , X86::UCOM_Fr },
781 { X86::UCOM_Fpr80 , X86::UCOM_Fr },
786 int Opc =
Lookup(OpcodeTable, Opcode);
787 assert(Opc != -1 &&
"FP Stack instruction not in OpcodeTable!");
799 { X86::ADD_FrST0 , X86::ADD_FPrST0 },
801 { X86::DIVR_FrST0, X86::DIVR_FPrST0 },
802 { X86::DIV_FrST0 , X86::DIV_FPrST0 },
804 { X86::IST_F16m , X86::IST_FP16m },
805 { X86::IST_F32m , X86::IST_FP32m },
807 { X86::MUL_FrST0 , X86::MUL_FPrST0 },
809 { X86::ST_F32m , X86::ST_FP32m },
810 { X86::ST_F64m , X86::ST_FP64m },
811 { X86::ST_Frr , X86::ST_FPrr },
813 { X86::SUBR_FrST0, X86::SUBR_FPrST0 },
814 { X86::SUB_FrST0 , X86::SUB_FPrST0 },
816 { X86::UCOM_FIr , X86::UCOM_FIPr },
818 { X86::UCOM_FPr , X86::UCOM_FPPr },
819 { X86::UCOM_Fr , X86::UCOM_FPr },
836 int Opcode =
Lookup(PopTable, I->getOpcode());
838 I->setDesc(TII->
get(Opcode));
839 if (Opcode == X86::UCOM_FPPr)
842 I =
BuildMI(*MBB, ++I, dl, TII->
get(X86::ST_FPrr)).addReg(X86::ST0);
851 if (getStackEntry(0) == FPRegNo) {
859 I = freeStackSlotBefore(++I, FPRegNo);
866 unsigned STReg = getSTReg(FPRegNo);
867 unsigned OldSlot = getSlot(FPRegNo);
868 unsigned TopReg = Stack[StackTop-1];
869 Stack[OldSlot] = TopReg;
870 RegMap[TopReg] = OldSlot;
871 RegMap[FPRegNo] = ~0;
872 Stack[--StackTop] = ~0;
881 unsigned Defs =
Mask;
883 for (
unsigned i = 0; i < StackTop; ++i) {
884 unsigned RegNo = Stack[i];
885 if (!(Defs & (1 << RegNo)))
887 Kills |= (1 << RegNo);
890 Defs &= ~(1 << RegNo);
892 assert((Kills & Defs) == 0 &&
"Register needs killing and def'ing?");
895 while (Kills && Defs) {
898 LLVM_DEBUG(
dbgs() <<
"Renaming %fp" << KReg <<
" as imp %fp" << DReg
900 std::swap(Stack[getSlot(KReg)], Stack[getSlot(DReg)]);
902 Kills &= ~(1 << KReg);
903 Defs &= ~(1 << DReg);
907 if (Kills && I != MBB->
begin()) {
910 unsigned KReg = getStackEntry(0);
911 if (!(Kills & (1 << KReg)))
915 Kills &= ~(1 << KReg);
923 freeStackSlotBefore(I, KReg);
924 Kills &= ~(1 << KReg);
933 Defs &= ~(1 << DReg);
944 void FPS::shuffleStackTop(
const unsigned char *FixStack,
950 unsigned OldReg = getStackEntry(FixCount);
952 unsigned Reg = FixStack[FixCount];
958 moveToTop(OldReg, I);
969 unsigned STReturns = 0;
972 for (
const auto &MO : I->operands()) {
976 unsigned R = MO.getReg() - X86::FP0;
980 assert(MO.isDef() && MO.isImplicit());
999 for (
unsigned I = 0; I <
N; ++
I)
1009 unsigned FirstFPRegOp = ~0U, SecondFPRegOp = ~0U;
1010 unsigned LiveMask = 0;
1022 "Ret only defs operands, and values aren't live beyond it");
1024 if (FirstFPRegOp == ~0U)
1027 assert(SecondFPRegOp == ~0U &&
"More than two fp operands!");
1040 adjustLiveRegs(LiveMask, MI);
1041 if (!LiveMask)
return;
1047 if (SecondFPRegOp == ~0U) {
1049 assert(StackTop == 1 && FirstFPRegOp == getStackEntry(0) &&
1050 "Top of stack not the right register for RET!");
1062 if (StackTop == 1) {
1063 assert(FirstFPRegOp == SecondFPRegOp && FirstFPRegOp == getStackEntry(0)&&
1064 "Stack misconfiguration for RET!");
1068 unsigned NewReg = ScratchFPReg;
1069 duplicateToTop(FirstFPRegOp, NewReg, MI);
1070 FirstFPRegOp = NewReg;
1074 assert(StackTop == 2 &&
"Must have two values live!");
1078 if (getStackEntry(0) == SecondFPRegOp) {
1079 assert(getStackEntry(1) == FirstFPRegOp &&
"Unknown regs live");
1080 moveToTop(FirstFPRegOp, MI);
1085 assert(getStackEntry(0) == FirstFPRegOp &&
"Unknown regs live");
1086 assert(getStackEntry(1) == SecondFPRegOp &&
"Unknown regs live");
1110 "Can only handle fst* & ftst instructions!");
1122 if (!KillsSrc && (MI.
getOpcode() == X86::IST_Fp64m32 ||
1135 duplicateToTop(Reg, ScratchFPReg, I);
1150 }
else if (KillsSrc) {
1168 assert(NumOps >= 2 &&
"FPRW instructions must have 2 ops!!");
1202 { X86::ADD_Fp32 , X86::ADD_FST0r },
1203 { X86::ADD_Fp64 , X86::ADD_FST0r },
1204 { X86::ADD_Fp80 , X86::ADD_FST0r },
1205 { X86::DIV_Fp32 , X86::DIV_FST0r },
1206 { X86::DIV_Fp64 , X86::DIV_FST0r },
1207 { X86::DIV_Fp80 , X86::DIV_FST0r },
1208 { X86::MUL_Fp32 , X86::MUL_FST0r },
1209 { X86::MUL_Fp64 , X86::MUL_FST0r },
1210 { X86::MUL_Fp80 , X86::MUL_FST0r },
1211 { X86::SUB_Fp32 , X86::SUB_FST0r },
1212 { X86::SUB_Fp64 , X86::SUB_FST0r },
1213 { X86::SUB_Fp80 , X86::SUB_FST0r },
1218 { X86::ADD_Fp32 , X86::ADD_FST0r },
1219 { X86::ADD_Fp64 , X86::ADD_FST0r },
1220 { X86::ADD_Fp80 , X86::ADD_FST0r },
1221 { X86::DIV_Fp32 , X86::DIVR_FST0r },
1222 { X86::DIV_Fp64 , X86::DIVR_FST0r },
1223 { X86::DIV_Fp80 , X86::DIVR_FST0r },
1224 { X86::MUL_Fp32 , X86::MUL_FST0r },
1225 { X86::MUL_Fp64 , X86::MUL_FST0r },
1226 { X86::MUL_Fp80 , X86::MUL_FST0r },
1227 { X86::SUB_Fp32 , X86::SUBR_FST0r },
1228 { X86::SUB_Fp64 , X86::SUBR_FST0r },
1229 { X86::SUB_Fp80 , X86::SUBR_FST0r },
1234 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1235 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1236 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1237 { X86::DIV_Fp32 , X86::DIVR_FrST0 },
1238 { X86::DIV_Fp64 , X86::DIVR_FrST0 },
1239 { X86::DIV_Fp80 , X86::DIVR_FrST0 },
1240 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1241 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1242 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1243 { X86::SUB_Fp32 , X86::SUBR_FrST0 },
1244 { X86::SUB_Fp64 , X86::SUBR_FrST0 },
1245 { X86::SUB_Fp80 , X86::SUBR_FrST0 },
1250 { X86::ADD_Fp32 , X86::ADD_FrST0 },
1251 { X86::ADD_Fp64 , X86::ADD_FrST0 },
1252 { X86::ADD_Fp80 , X86::ADD_FrST0 },
1253 { X86::DIV_Fp32 , X86::DIV_FrST0 },
1254 { X86::DIV_Fp64 , X86::DIV_FrST0 },
1255 { X86::DIV_Fp80 , X86::DIV_FrST0 },
1256 { X86::MUL_Fp32 , X86::MUL_FrST0 },
1257 { X86::MUL_Fp64 , X86::MUL_FrST0 },
1258 { X86::MUL_Fp80 , X86::MUL_FrST0 },
1259 { X86::SUB_Fp32 , X86::SUB_FrST0 },
1260 { X86::SUB_Fp64 , X86::SUB_FrST0 },
1261 { X86::SUB_Fp80 , X86::SUB_FrST0 },
1279 assert(NumOperands == 3 &&
"Illegal TwoArgFP instruction!");
1287 unsigned TOS = getStackEntry(0);
1291 if (Op0 != TOS && Op1 != TOS) {
1298 }
else if (KillsOp1) {
1307 duplicateToTop(Op0, Dest, I);
1311 }
else if (!KillsOp0 && !KillsOp1) {
1315 duplicateToTop(Op0, Dest, I);
1322 assert((TOS == Op0 || TOS == Op1) && (KillsOp0 || KillsOp1) &&
1323 "Stack conditions not set up right!");
1328 bool isForward = TOS == Op0;
1329 bool updateST0 = (TOS == Op0 && !KillsOp1) || (TOS == Op1 && !KillsOp0);
1343 assert(Opcode != -1 &&
"Unknown TwoArgFP pseudo instruction!");
1346 unsigned NotTOS = (TOS == Op0) ? Op1 : Op0;
1350 I =
BuildMI(*MBB, I, dl, TII->
get(Opcode)).addReg(getSTReg(NotTOS));
1354 if (KillsOp0 && KillsOp1 && Op0 != Op1) {
1355 assert(!updateST0 &&
"Should have updated other operand!");
1361 unsigned UpdatedSlot = getSlot(updateST0 ? TOS : NotTOS);
1362 assert(UpdatedSlot < StackTop && Dest < 7);
1363 Stack[UpdatedSlot] = Dest;
1364 RegMap[Dest] = UpdatedSlot;
1377 assert(NumOperands == 2 &&
"Illegal FUCOM* instruction!");
1393 if (KillsOp0) freeStackSlotAfter(I, Op0);
1394 if (KillsOp1 && Op0 != Op1) freeStackSlotAfter(I, Op1);
1419 if (Op0 != Op1 && KillsOp1) {
1421 freeStackSlotAfter(I, Op1);
1445 case TargetOpcode::COPY: {
1454 assert(isLive(SrcFP) &&
"Cannot copy dead register");
1458 unsigned Slot = getSlot(SrcFP);
1459 Stack[Slot] = DstFP;
1460 RegMap[DstFP] = Slot;
1464 duplicateToTop(SrcFP, DstFP, Inst);
1469 case TargetOpcode::IMPLICIT_DEF: {
1472 LLVM_DEBUG(
dbgs() <<
"Emitting LD_F0 for implicit FP" << Reg <<
'\n');
1512 unsigned STUses = 0, STDefs = 0, STClobbers = 0, STDeadDefs = 0;
1513 unsigned NumOps = 0;
1527 unsigned STReg = MO.
getReg() - X86::FP0;
1540 STUses |= (1u << STReg);
1544 STDefs |= (1u << STReg);
1546 STDeadDefs |= (1u << STReg);
1549 STClobbers |= (1u << STReg);
1557 MI.
emitError(
"fixed input regs must be last on the x87 stack");
1562 MI.
emitError(
"output regs must be last on the x87 stack");
1568 if (STClobbers && !
isMask_32(STDefs | STClobbers))
1569 MI.
emitError(
"clobbers must be last on the x87 stack");
1572 unsigned STPopped = STUses & (STDefs | STClobbers);
1574 MI.
emitError(
"implicitly popped regs must be last on the x87 stack");
1577 LLVM_DEBUG(
dbgs() <<
"Asm uses " << NumSTUses <<
" fixed regs, pops " 1578 << NumSTPopped <<
", and defines " << NumSTDefs
1585 if (FRegIdx.
count(I)) {
1587 "Operands with constraint \"f\" cannot overlap with defs");
1593 unsigned FPKills = ((1u << NumFPRegs) - 1) & ~0xff;
1604 FPKills |= 1U << FPReg;
1608 FPKills &= ~(STDefs | STClobbers);
1611 unsigned char STUsesArray[8];
1613 for (
unsigned I = 0; I < NumSTUses; ++
I)
1616 shuffleStackTop(STUsesArray, NumSTUses, Inst);
1618 dbgs() <<
"Before asm: ";
1630 if (FRegIdx.
count(i))
1632 Op.
setReg(getSTReg(FPReg));
1635 Op.
setReg(X86::ST0 + FPReg);
1639 StackTop -= NumSTPopped;
1641 for (
unsigned i = 0; i < NumSTDefs; ++i)
1642 pushReg(NumSTDefs - i - 1);
1654 freeStackSlotAfter(Inst, FPReg);
1655 FPKills &= ~(1U << FPReg);
1663 Inst = MBB->
erase(Inst);
1667 if (Inst == MBB->
begin()) {
1683 if (I->isDebugInstr())
1686 std::bitset<8> Defs;
1690 for (
auto &MO : I->operands()) {
1694 unsigned Reg = MO.getReg() - X86::FP0;
1707 for (
auto *MO : Uses)
bool reg_nodbg_empty(unsigned RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions...
static const TableEntry OpcodeTable[]
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isCall(QueryType Type=AnyInBundle) const
unsigned getBundle(unsigned N, bool Out) const
getBundle - Return the ingoing (Out = false) or outgoing (Out = true) bundle number for basic block N...
void emitError(StringRef Msg) const
Emit an error referring to the source location of this instruction.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
static unsigned getConcreteOpcode(unsigned Opcode)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
Register calling convention used for parameters transfer optimization.
AddrNumOperands - Total number of operands in a memory reference.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
bool contains(MCPhysReg Reg) const
Returns true if register Reg is contained in the set.
static const TableEntry ReverseSTiTable[]
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
AnalysisUsage & addRequired()
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
static const TableEntry ForwardST0Table[]
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LiveInVector::const_iterator livein_iterator
INLINEASM - Represents an inline asm block.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static unsigned getFPReg(const MachineOperand &MO)
getFPReg - Return the X86::FPx register number for the specified operand.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
AnalysisUsage & addPreservedID(const void *ID)
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
virtual const TargetInstrInfo * getInstrInfo() const
reverse_iterator rbegin()
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
static const TableEntry PopTable[]
TargetInstrInfo - Interface to description of machine instruction set.
bool isReturn(QueryType Type=AnyInBundle) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static const TableEntry ForwardSTiTable[]
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void addLiveOuts(const MachineBasicBlock &MBB)
Adds all live-out registers of basic block MBB.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
livein_iterator livein_end() const
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
Represent the analysis usage information of a pass.
void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
static unsigned getKind(unsigned Flags)
FunctionPass class - This class is used to implement most global optimizations.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void DeleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
bool isImplicitDef() const
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned countPopulation(T Value)
Count the number of set bits in a value.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::pair< iterator, bool > insert(NodeRef N)
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
FunctionPass * createX86FloatingPointStackifierPass()
This function returns a pass which converts floating-point register references and pseudo instruction...
unsigned getNumBundles() const
getNumBundles - Return the total number of bundles in the CFG.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
static const TableEntry ReverseST0Table[]
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
LLVM_NODISCARD bool empty() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
#define ASSERT_SORTED(TABLE)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void initializeEdgeBundlesPass(PassRegistry &)
StringRef - Represent a constant reference to a string, i.e.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
#define LLVM_ATTRIBUTE_UNUSED
const MachineOperand & getOperand(unsigned i) const
livein_iterator livein_begin() const
Properties which a MachineFunction may have at a given point in time.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.