OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 // Validate the live range computations. Do it outside the timing | 375 // Validate the live range computations. Do it outside the timing |
376 // code. TODO: Put this under a flag. | 376 // code. TODO: Put this under a flag. |
377 bool ValidLiveness = Func->validateLiveness(); | 377 bool ValidLiveness = Func->validateLiveness(); |
378 assert(ValidLiveness); | 378 assert(ValidLiveness); |
379 (void)ValidLiveness; // used only in assert() | 379 (void)ValidLiveness; // used only in assert() |
380 ComputedLiveRanges = true; | 380 ComputedLiveRanges = true; |
381 // The post-codegen dump is done here, after liveness analysis and | 381 // The post-codegen dump is done here, after liveness analysis and |
382 // associated cleanup, to make the dump cleaner and more useful. | 382 // associated cleanup, to make the dump cleaner and more useful. |
383 Func->dump("After initial x8632 codegen"); | 383 Func->dump("After initial x8632 codegen"); |
384 Timer T_regAlloc; | 384 Timer T_regAlloc; |
| 385 Func->getVMetadata()->init(); |
385 regAlloc(); | 386 regAlloc(); |
386 if (Func->hasError()) | 387 if (Func->hasError()) |
387 return; | 388 return; |
388 T_regAlloc.printElapsedUs(Context, "regAlloc()"); | 389 T_regAlloc.printElapsedUs(Context, "regAlloc()"); |
389 Func->dump("After linear scan regalloc"); | 390 Func->dump("After linear scan regalloc"); |
390 | 391 |
391 // Stack frame mapping. | 392 // Stack frame mapping. |
392 Timer T_genFrame; | 393 Timer T_genFrame; |
393 Func->genFrame(); | 394 Func->genFrame(); |
394 if (Func->hasError()) | 395 if (Func->hasError()) |
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 if (Dest->getType() == IceType_i8) | 1584 if (Dest->getType() == IceType_i8) |
1584 _mov(T, Src0, RegX8632::Reg_eax); | 1585 _mov(T, Src0, RegX8632::Reg_eax); |
1585 else | 1586 else |
1586 _mov(T, Src0); | 1587 _mov(T, Src0); |
1587 _imul(T, Src1); | 1588 _imul(T, Src1); |
1588 _mov(Dest, T); | 1589 _mov(Dest, T); |
1589 break; | 1590 break; |
1590 case InstArithmetic::Shl: | 1591 case InstArithmetic::Shl: |
1591 _mov(T, Src0); | 1592 _mov(T, Src0); |
1592 if (!llvm::isa<Constant>(Src1)) | 1593 if (!llvm::isa<Constant>(Src1)) |
1593 Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx); | 1594 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); |
1594 _shl(T, Src1); | 1595 _shl(T, Src1); |
1595 _mov(Dest, T); | 1596 _mov(Dest, T); |
1596 break; | 1597 break; |
1597 case InstArithmetic::Lshr: | 1598 case InstArithmetic::Lshr: |
1598 _mov(T, Src0); | 1599 _mov(T, Src0); |
1599 if (!llvm::isa<Constant>(Src1)) | 1600 if (!llvm::isa<Constant>(Src1)) |
1600 Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx); | 1601 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); |
1601 _shr(T, Src1); | 1602 _shr(T, Src1); |
1602 _mov(Dest, T); | 1603 _mov(Dest, T); |
1603 break; | 1604 break; |
1604 case InstArithmetic::Ashr: | 1605 case InstArithmetic::Ashr: |
1605 _mov(T, Src0); | 1606 _mov(T, Src0); |
1606 if (!llvm::isa<Constant>(Src1)) | 1607 if (!llvm::isa<Constant>(Src1)) |
1607 Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx); | 1608 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); |
1608 _sar(T, Src1); | 1609 _sar(T, Src1); |
1609 _mov(Dest, T); | 1610 _mov(Dest, T); |
1610 break; | 1611 break; |
1611 case InstArithmetic::Udiv: | 1612 case InstArithmetic::Udiv: |
1612 // div and idiv are the few arithmetic operators that do not allow | 1613 // div and idiv are the few arithmetic operators that do not allow |
1613 // immediates as the operand. | 1614 // immediates as the operand. |
1614 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1615 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
1615 if (Dest->getType() == IceType_i8) { | 1616 if (Dest->getType() == IceType_i8) { |
1616 Variable *T_ah = NULL; | 1617 Variable *T_ah = NULL; |
1617 Constant *Zero = Ctx->getConstantZero(IceType_i8); | 1618 Constant *Zero = Ctx->getConstantZero(IceType_i8); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 Operand *Src0Lo = loOperand(Src0); | 1719 Operand *Src0Lo = loOperand(Src0); |
1719 Operand *Src0Hi = hiOperand(Src0); | 1720 Operand *Src0Hi = hiOperand(Src0); |
1720 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1721 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
1721 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1722 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
1722 Variable *T_Lo = NULL, *T_Hi = NULL; | 1723 Variable *T_Lo = NULL, *T_Hi = NULL; |
1723 _mov(T_Lo, Src0Lo); | 1724 _mov(T_Lo, Src0Lo); |
1724 _mov(DestLo, T_Lo); | 1725 _mov(DestLo, T_Lo); |
1725 _mov(T_Hi, Src0Hi); | 1726 _mov(T_Hi, Src0Hi); |
1726 _mov(DestHi, T_Hi); | 1727 _mov(DestHi, T_Hi); |
1727 } else { | 1728 } else { |
1728 const bool AllowOverlap = true; | |
1729 // RI is either a physical register or an immediate. | 1729 // RI is either a physical register or an immediate. |
1730 Operand *RI = legalize(Src0, Legal_Reg | Legal_Imm, AllowOverlap); | 1730 Operand *RI = legalize(Src0, Legal_Reg | Legal_Imm); |
1731 if (isVectorType(Dest->getType())) | 1731 if (isVectorType(Dest->getType())) |
1732 _movp(Dest, RI); | 1732 _movp(Dest, RI); |
1733 else | 1733 else |
1734 _mov(Dest, RI); | 1734 _mov(Dest, RI); |
1735 } | 1735 } |
1736 } | 1736 } |
1737 | 1737 |
1738 void TargetX8632::lowerBr(const InstBr *Inst) { | 1738 void TargetX8632::lowerBr(const InstBr *Inst) { |
1739 if (Inst->isUnconditional()) { | 1739 if (Inst->isUnconditional()) { |
1740 _br(Inst->getTargetUnconditional()); | 1740 _br(Inst->getTargetUnconditional()); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 // Copy arguments to be passed in registers to the appropriate | 1823 // Copy arguments to be passed in registers to the appropriate |
1824 // registers. | 1824 // registers. |
1825 // TODO: Investigate the impact of lowering arguments passed in | 1825 // TODO: Investigate the impact of lowering arguments passed in |
1826 // registers after lowering stack arguments as opposed to the other | 1826 // registers after lowering stack arguments as opposed to the other |
1827 // way around. Lowering register arguments after stack arguments may | 1827 // way around. Lowering register arguments after stack arguments may |
1828 // reduce register pressure. On the other hand, lowering register | 1828 // reduce register pressure. On the other hand, lowering register |
1829 // arguments first (before stack arguments) may result in more compact | 1829 // arguments first (before stack arguments) may result in more compact |
1830 // code, as the memory operand displacements may end up being smaller | 1830 // code, as the memory operand displacements may end up being smaller |
1831 // before any stack adjustment is done. | 1831 // before any stack adjustment is done. |
1832 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { | 1832 for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) { |
1833 Variable *Reg = legalizeToVar(XmmArgs[i], false, RegX8632::Reg_xmm0 + i); | 1833 Variable *Reg = legalizeToVar(XmmArgs[i], RegX8632::Reg_xmm0 + i); |
1834 // Generate a FakeUse of register arguments so that they do not get | 1834 // Generate a FakeUse of register arguments so that they do not get |
1835 // dead code eliminated as a result of the FakeKill of scratch | 1835 // dead code eliminated as a result of the FakeKill of scratch |
1836 // registers after the call. | 1836 // registers after the call. |
1837 Context.insert(InstFakeUse::create(Func, Reg)); | 1837 Context.insert(InstFakeUse::create(Func, Reg)); |
1838 } | 1838 } |
1839 // Generate the call instruction. Assign its result to a temporary | 1839 // Generate the call instruction. Assign its result to a temporary |
1840 // with high register allocation weight. | 1840 // with high register allocation weight. |
1841 Variable *Dest = Instr->getDest(); | 1841 Variable *Dest = Instr->getDest(); |
1842 // ReturnReg doubles as ReturnRegLo as necessary. | 1842 // ReturnReg doubles as ReturnRegLo as necessary. |
1843 Variable *ReturnReg = NULL; | 1843 Variable *ReturnReg = NULL; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 if (!Dest) | 1907 if (!Dest) |
1908 return; | 1908 return; |
1909 | 1909 |
1910 // Assign the result of the call to Dest. | 1910 // Assign the result of the call to Dest. |
1911 if (ReturnReg) { | 1911 if (ReturnReg) { |
1912 if (ReturnRegHi) { | 1912 if (ReturnRegHi) { |
1913 assert(Dest->getType() == IceType_i64); | 1913 assert(Dest->getType() == IceType_i64); |
1914 split64(Dest); | 1914 split64(Dest); |
1915 Variable *DestLo = Dest->getLo(); | 1915 Variable *DestLo = Dest->getLo(); |
1916 Variable *DestHi = Dest->getHi(); | 1916 Variable *DestHi = Dest->getHi(); |
1917 DestLo->setPreferredRegister(ReturnReg, false); | |
1918 DestHi->setPreferredRegister(ReturnRegHi, false); | |
1919 _mov(DestLo, ReturnReg); | 1917 _mov(DestLo, ReturnReg); |
1920 _mov(DestHi, ReturnRegHi); | 1918 _mov(DestHi, ReturnRegHi); |
1921 } else { | 1919 } else { |
1922 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || | 1920 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || |
1923 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || | 1921 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || |
1924 isVectorType(Dest->getType())); | 1922 isVectorType(Dest->getType())); |
1925 Dest->setPreferredRegister(ReturnReg, false); | |
1926 if (isVectorType(Dest->getType())) { | 1923 if (isVectorType(Dest->getType())) { |
1927 _movp(Dest, ReturnReg); | 1924 _movp(Dest, ReturnReg); |
1928 } else { | 1925 } else { |
1929 _mov(Dest, ReturnReg); | 1926 _mov(Dest, ReturnReg); |
1930 } | 1927 } |
1931 } | 1928 } |
1932 } else if (Dest->getType() == IceType_f32 || Dest->getType() == IceType_f64) { | 1929 } else if (Dest->getType() == IceType_f32 || Dest->getType() == IceType_f64) { |
1933 // Special treatment for an FP function which returns its result in | 1930 // Special treatment for an FP function which returns its result in |
1934 // st(0). | 1931 // st(0). |
1935 // If Dest ends up being a physical xmm register, the fstp emit code | 1932 // If Dest ends up being a physical xmm register, the fstp emit code |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 } else { | 2127 } else { |
2131 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2128 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2132 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2129 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2133 Variable *T_1 = makeReg(IceType_i32); | 2130 Variable *T_1 = makeReg(IceType_i32); |
2134 Variable *T_2 = makeReg(Dest->getType()); | 2131 Variable *T_2 = makeReg(Dest->getType()); |
2135 _cvtt(T_1, Src0RM); | 2132 _cvtt(T_1, Src0RM); |
2136 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2133 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2137 if (Dest->getType() == IceType_i1) | 2134 if (Dest->getType() == IceType_i1) |
2138 _and(T_2, Ctx->getConstantInt32(IceType_i1, 1)); | 2135 _and(T_2, Ctx->getConstantInt32(IceType_i1, 1)); |
2139 _mov(Dest, T_2); | 2136 _mov(Dest, T_2); |
2140 T_2->setPreferredRegister(T_1, true); | |
2141 } | 2137 } |
2142 break; | 2138 break; |
2143 case InstCast::Fptoui: | 2139 case InstCast::Fptoui: |
2144 if (isVectorType(Dest->getType())) { | 2140 if (isVectorType(Dest->getType())) { |
2145 assert(Dest->getType() == IceType_v4i32 && | 2141 assert(Dest->getType() == IceType_v4i32 && |
2146 Inst->getSrc(0)->getType() == IceType_v4f32); | 2142 Inst->getSrc(0)->getType() == IceType_v4f32); |
2147 const SizeT MaxSrcs = 1; | 2143 const SizeT MaxSrcs = 1; |
2148 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); | 2144 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); |
2149 Call->addArg(Inst->getSrc(0)); | 2145 Call->addArg(Inst->getSrc(0)); |
2150 lowerCall(Call); | 2146 lowerCall(Call); |
(...skipping 16 matching lines...) Expand all Loading... |
2167 } else { | 2163 } else { |
2168 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2164 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2169 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2165 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2170 Variable *T_1 = makeReg(IceType_i32); | 2166 Variable *T_1 = makeReg(IceType_i32); |
2171 Variable *T_2 = makeReg(Dest->getType()); | 2167 Variable *T_2 = makeReg(Dest->getType()); |
2172 _cvtt(T_1, Src0RM); | 2168 _cvtt(T_1, Src0RM); |
2173 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2169 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2174 if (Dest->getType() == IceType_i1) | 2170 if (Dest->getType() == IceType_i1) |
2175 _and(T_2, Ctx->getConstantInt32(IceType_i1, 1)); | 2171 _and(T_2, Ctx->getConstantInt32(IceType_i1, 1)); |
2176 _mov(Dest, T_2); | 2172 _mov(Dest, T_2); |
2177 T_2->setPreferredRegister(T_1, true); | |
2178 } | 2173 } |
2179 break; | 2174 break; |
2180 case InstCast::Sitofp: | 2175 case InstCast::Sitofp: |
2181 if (isVectorType(Dest->getType())) { | 2176 if (isVectorType(Dest->getType())) { |
2182 assert(Dest->getType() == IceType_v4f32 && | 2177 assert(Dest->getType() == IceType_v4f32 && |
2183 Inst->getSrc(0)->getType() == IceType_v4i32); | 2178 Inst->getSrc(0)->getType() == IceType_v4i32); |
2184 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2185 Variable *T = makeReg(Dest->getType()); | 2180 Variable *T = makeReg(Dest->getType()); |
2186 _cvt(T, Src0RM); | 2181 _cvt(T, Src0RM); |
2187 _movp(Dest, T); | 2182 _movp(Dest, T); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2679 IsSrc1ImmOrReg = true; | 2674 IsSrc1ImmOrReg = true; |
2680 } | 2675 } |
2681 | 2676 |
2682 // Try to fuse a compare immediately followed by a conditional branch. This | 2677 // Try to fuse a compare immediately followed by a conditional branch. This |
2683 // is possible when the compare dest and the branch source operands are the | 2678 // is possible when the compare dest and the branch source operands are the |
2684 // same, and are their only uses. TODO: implement this optimization for i64. | 2679 // same, and are their only uses. TODO: implement this optimization for i64. |
2685 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { | 2680 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { |
2686 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && | 2681 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && |
2687 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { | 2682 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { |
2688 NextBr->setDeleted(); | 2683 NextBr->setDeleted(); |
2689 Operand *Src0RM = legalize( | 2684 Operand *Src0RM = |
2690 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); | 2685 legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); |
2691 _cmp(Src0RM, Src1); | 2686 _cmp(Src0RM, Src1); |
2692 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), | 2687 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), |
2693 NextBr->getTargetFalse()); | 2688 NextBr->getTargetFalse()); |
2694 // Skip over the following branch instruction. | 2689 // Skip over the following branch instruction. |
2695 Context.advanceNext(); | 2690 Context.advanceNext(); |
2696 return; | 2691 return; |
2697 } | 2692 } |
2698 } | 2693 } |
2699 | 2694 |
2700 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: | 2695 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: |
(...skipping 28 matching lines...) Expand all Loading... |
2729 _br(TableIcmp64[Index].C3, LabelTrue); | 2724 _br(TableIcmp64[Index].C3, LabelTrue); |
2730 Context.insert(LabelFalse); | 2725 Context.insert(LabelFalse); |
2731 Context.insert(InstFakeUse::create(Func, Dest)); | 2726 Context.insert(InstFakeUse::create(Func, Dest)); |
2732 _mov(Dest, Zero); | 2727 _mov(Dest, Zero); |
2733 Context.insert(LabelTrue); | 2728 Context.insert(LabelTrue); |
2734 } | 2729 } |
2735 return; | 2730 return; |
2736 } | 2731 } |
2737 | 2732 |
2738 // cmp b, c | 2733 // cmp b, c |
2739 Operand *Src0RM = legalize( | 2734 Operand *Src0RM = |
2740 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); | 2735 legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); |
2741 InstX8632Label *Label = InstX8632Label::create(Func, this); | 2736 InstX8632Label *Label = InstX8632Label::create(Func, this); |
2742 _cmp(Src0RM, Src1); | 2737 _cmp(Src0RM, Src1); |
2743 _mov(Dest, One); | 2738 _mov(Dest, One); |
2744 _br(getIcmp32Mapping(Inst->getCondition()), Label); | 2739 _br(getIcmp32Mapping(Inst->getCondition()), Label); |
2745 Context.insert(InstFakeUse::create(Func, Dest)); | 2740 Context.insert(InstFakeUse::create(Func, Dest)); |
2746 _mov(Dest, Zero); | 2741 _mov(Dest, Zero); |
2747 Context.insert(Label); | 2742 Context.insert(Label); |
2748 } | 2743 } |
2749 | 2744 |
2750 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { | 2745 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3581 Str << "<null>"; | 3576 Str << "<null>"; |
3582 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; | 3577 Str << ", Shift=" << Shift << ", Offset=" << Offset << "\n"; |
3583 } | 3578 } |
3584 | 3579 |
3585 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, | 3580 bool matchTransitiveAssign(const VariablesMetadata *VMetadata, Variable *&Var, |
3586 const Inst *&Reason) { | 3581 const Inst *&Reason) { |
3587 // Var originates from Var=SrcVar ==> | 3582 // Var originates from Var=SrcVar ==> |
3588 // set Var:=SrcVar | 3583 // set Var:=SrcVar |
3589 if (Var == NULL) | 3584 if (Var == NULL) |
3590 return false; | 3585 return false; |
3591 if (const Inst *VarAssign = VMetadata->getDefinition(Var)) { | 3586 if (const Inst *VarAssign = VMetadata->getSingleDefinition(Var)) { |
| 3587 assert(!VMetadata->isMultiDef(Var)); |
3592 if (llvm::isa<InstAssign>(VarAssign)) { | 3588 if (llvm::isa<InstAssign>(VarAssign)) { |
3593 Operand *SrcOp = VarAssign->getSrc(0); | 3589 Operand *SrcOp = VarAssign->getSrc(0); |
3594 assert(SrcOp); | 3590 assert(SrcOp); |
3595 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { | 3591 if (Variable *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) { |
3596 if (!VMetadata->isMultiDef(SrcVar) && | 3592 if (!VMetadata->isMultiDef(SrcVar) && |
3597 // TODO: ensure SrcVar stays single-BB | 3593 // TODO: ensure SrcVar stays single-BB |
3598 true) { | 3594 true) { |
3599 Var = SrcVar; | 3595 Var = SrcVar; |
3600 Reason = VarAssign; | 3596 Reason = VarAssign; |
3601 return true; | 3597 return true; |
3602 } | 3598 } |
3603 } | 3599 } |
3604 } | 3600 } |
3605 } | 3601 } |
3606 return false; | 3602 return false; |
3607 } | 3603 } |
3608 | 3604 |
3609 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, | 3605 bool matchCombinedBaseIndex(const VariablesMetadata *VMetadata, Variable *&Base, |
3610 Variable *&Index, uint16_t &Shift, | 3606 Variable *&Index, uint16_t &Shift, |
3611 const Inst *&Reason) { | 3607 const Inst *&Reason) { |
3612 // Index==NULL && Base is Base=Var1+Var2 ==> | 3608 // Index==NULL && Base is Base=Var1+Var2 ==> |
3613 // set Base=Var1, Index=Var2, Shift=0 | 3609 // set Base=Var1, Index=Var2, Shift=0 |
3614 if (Base == NULL) | 3610 if (Base == NULL) |
3615 return false; | 3611 return false; |
3616 if (Index != NULL) | 3612 if (Index != NULL) |
3617 return false; | 3613 return false; |
3618 const Inst *BaseInst = VMetadata->getDefinition(Base); | 3614 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); |
3619 if (BaseInst == NULL) | 3615 if (BaseInst == NULL) |
3620 return false; | 3616 return false; |
| 3617 assert(!VMetadata->isMultiDef(Base)); |
3621 if (BaseInst->getSrcSize() < 2) | 3618 if (BaseInst->getSrcSize() < 2) |
3622 return false; | 3619 return false; |
3623 if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) { | 3620 if (Variable *Var1 = llvm::dyn_cast<Variable>(BaseInst->getSrc(0))) { |
3624 if (VMetadata->isMultiDef(Var1)) | 3621 if (VMetadata->isMultiDef(Var1)) |
3625 return false; | 3622 return false; |
3626 if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) { | 3623 if (Variable *Var2 = llvm::dyn_cast<Variable>(BaseInst->getSrc(1))) { |
3627 if (VMetadata->isMultiDef(Var2)) | 3624 if (VMetadata->isMultiDef(Var2)) |
3628 return false; | 3625 return false; |
3629 if (isAdd(BaseInst) && | 3626 if (isAdd(BaseInst) && |
3630 // TODO: ensure Var1 and Var2 stay single-BB | 3627 // TODO: ensure Var1 and Var2 stay single-BB |
3631 true) { | 3628 true) { |
3632 Base = Var1; | 3629 Base = Var1; |
3633 Index = Var2; | 3630 Index = Var2; |
3634 Shift = 0; // should already have been 0 | 3631 Shift = 0; // should already have been 0 |
3635 Reason = BaseInst; | 3632 Reason = BaseInst; |
3636 return true; | 3633 return true; |
3637 } | 3634 } |
3638 } | 3635 } |
3639 } | 3636 } |
3640 return false; | 3637 return false; |
3641 } | 3638 } |
3642 | 3639 |
3643 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, | 3640 bool matchShiftedIndex(const VariablesMetadata *VMetadata, Variable *&Index, |
3644 uint16_t &Shift, const Inst *&Reason) { | 3641 uint16_t &Shift, const Inst *&Reason) { |
3645 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> | 3642 // Index is Index=Var*Const && log2(Const)+Shift<=3 ==> |
3646 // Index=Var, Shift+=log2(Const) | 3643 // Index=Var, Shift+=log2(Const) |
3647 if (Index == NULL) | 3644 if (Index == NULL) |
3648 return false; | 3645 return false; |
3649 const Inst *IndexInst = VMetadata->getDefinition(Index); | 3646 const Inst *IndexInst = VMetadata->getSingleDefinition(Index); |
3650 if (IndexInst == NULL) | 3647 if (IndexInst == NULL) |
3651 return false; | 3648 return false; |
| 3649 assert(!VMetadata->isMultiDef(Index)); |
3652 if (IndexInst->getSrcSize() < 2) | 3650 if (IndexInst->getSrcSize() < 2) |
3653 return false; | 3651 return false; |
3654 if (const InstArithmetic *ArithInst = | 3652 if (const InstArithmetic *ArithInst = |
3655 llvm::dyn_cast<InstArithmetic>(IndexInst)) { | 3653 llvm::dyn_cast<InstArithmetic>(IndexInst)) { |
3656 if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { | 3654 if (Variable *Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { |
3657 if (ConstantInteger32 *Const = | 3655 if (ConstantInteger32 *Const = |
3658 llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) { | 3656 llvm::dyn_cast<ConstantInteger32>(ArithInst->getSrc(1))) { |
3659 if (ArithInst->getOp() == InstArithmetic::Mul && | 3657 if (ArithInst->getOp() == InstArithmetic::Mul && |
3660 !VMetadata->isMultiDef(Var) && Const->getType() == IceType_i32) { | 3658 !VMetadata->isMultiDef(Var) && Const->getType() == IceType_i32) { |
3661 uint64_t Mult = Const->getValue(); | 3659 uint64_t Mult = Const->getValue(); |
(...skipping 28 matching lines...) Expand all Loading... |
3690 } | 3688 } |
3691 | 3689 |
3692 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, | 3690 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base, |
3693 int32_t &Offset, const Inst *&Reason) { | 3691 int32_t &Offset, const Inst *&Reason) { |
3694 // Base is Base=Var+Const || Base is Base=Const+Var ==> | 3692 // Base is Base=Var+Const || Base is Base=Const+Var ==> |
3695 // set Base=Var, Offset+=Const | 3693 // set Base=Var, Offset+=Const |
3696 // Base is Base=Var-Const ==> | 3694 // Base is Base=Var-Const ==> |
3697 // set Base=Var, Offset-=Const | 3695 // set Base=Var, Offset-=Const |
3698 if (Base == NULL) | 3696 if (Base == NULL) |
3699 return false; | 3697 return false; |
3700 const Inst *BaseInst = VMetadata->getDefinition(Base); | 3698 const Inst *BaseInst = VMetadata->getSingleDefinition(Base); |
3701 if (BaseInst == NULL) | 3699 if (BaseInst == NULL) |
3702 return false; | 3700 return false; |
| 3701 assert(!VMetadata->isMultiDef(Base)); |
3703 if (const InstArithmetic *ArithInst = | 3702 if (const InstArithmetic *ArithInst = |
3704 llvm::dyn_cast<const InstArithmetic>(BaseInst)) { | 3703 llvm::dyn_cast<const InstArithmetic>(BaseInst)) { |
3705 if (ArithInst->getOp() != InstArithmetic::Add && | 3704 if (ArithInst->getOp() != InstArithmetic::Add && |
3706 ArithInst->getOp() != InstArithmetic::Sub) | 3705 ArithInst->getOp() != InstArithmetic::Sub) |
3707 return false; | 3706 return false; |
3708 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; | 3707 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; |
3709 Variable *Var = NULL; | 3708 Variable *Var = NULL; |
3710 ConstantInteger32 *Const = NULL; | 3709 ConstantInteger32 *Const = NULL; |
3711 if (Variable *VariableOperand = | 3710 if (Variable *VariableOperand = |
3712 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { | 3711 llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3871 | 3870 |
3872 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { | 3871 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { |
3873 Func->setError("Phi found in regular instruction list"); | 3872 Func->setError("Phi found in regular instruction list"); |
3874 } | 3873 } |
3875 | 3874 |
3876 void TargetX8632::lowerRet(const InstRet *Inst) { | 3875 void TargetX8632::lowerRet(const InstRet *Inst) { |
3877 Variable *Reg = NULL; | 3876 Variable *Reg = NULL; |
3878 if (Inst->hasRetValue()) { | 3877 if (Inst->hasRetValue()) { |
3879 Operand *Src0 = legalize(Inst->getRetValue()); | 3878 Operand *Src0 = legalize(Inst->getRetValue()); |
3880 if (Src0->getType() == IceType_i64) { | 3879 if (Src0->getType() == IceType_i64) { |
3881 Variable *eax = legalizeToVar(loOperand(Src0), false, RegX8632::Reg_eax); | 3880 Variable *eax = legalizeToVar(loOperand(Src0), RegX8632::Reg_eax); |
3882 Variable *edx = legalizeToVar(hiOperand(Src0), false, RegX8632::Reg_edx); | 3881 Variable *edx = legalizeToVar(hiOperand(Src0), RegX8632::Reg_edx); |
3883 Reg = eax; | 3882 Reg = eax; |
3884 Context.insert(InstFakeUse::create(Func, edx)); | 3883 Context.insert(InstFakeUse::create(Func, edx)); |
3885 } else if (Src0->getType() == IceType_f32 || | 3884 } else if (Src0->getType() == IceType_f32 || |
3886 Src0->getType() == IceType_f64) { | 3885 Src0->getType() == IceType_f64) { |
3887 _fld(Src0); | 3886 _fld(Src0); |
3888 } else if (isVectorType(Src0->getType())) { | 3887 } else if (isVectorType(Src0->getType())) { |
3889 Reg = legalizeToVar(Src0, false, RegX8632::Reg_xmm0); | 3888 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); |
3890 } else { | 3889 } else { |
3891 _mov(Reg, Src0, RegX8632::Reg_eax); | 3890 _mov(Reg, Src0, RegX8632::Reg_eax); |
3892 } | 3891 } |
3893 } | 3892 } |
3894 _ret(Reg); | 3893 _ret(Reg); |
3895 // Add a fake use of esp to make sure esp stays alive for the entire | 3894 // Add a fake use of esp to make sure esp stays alive for the entire |
3896 // function. Otherwise post-call esp adjustments get dead-code | 3895 // function. Otherwise post-call esp adjustments get dead-code |
3897 // eliminated. TODO: Are there more places where the fake use | 3896 // eliminated. TODO: Are there more places where the fake use |
3898 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not | 3897 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not |
3899 // have a ret instruction. | 3898 // have a ret instruction. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3966 } | 3965 } |
3967 | 3966 |
3968 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: | 3967 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: |
3969 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); | 3968 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); |
3970 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3969 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
3971 InstX8632Label *Label = InstX8632Label::create(Func, this); | 3970 InstX8632Label *Label = InstX8632Label::create(Func, this); |
3972 | 3971 |
3973 if (Dest->getType() == IceType_i64) { | 3972 if (Dest->getType() == IceType_i64) { |
3974 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3973 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3975 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3974 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3976 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true); | 3975 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm); |
3977 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true); | 3976 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm); |
3978 _cmp(ConditionRM, Zero); | 3977 _cmp(ConditionRM, Zero); |
3979 _mov(DestLo, SrcLoRI); | 3978 _mov(DestLo, SrcLoRI); |
3980 _mov(DestHi, SrcHiRI); | 3979 _mov(DestHi, SrcHiRI); |
3981 _br(CondX86::Br_ne, Label); | 3980 _br(CondX86::Br_ne, Label); |
3982 Context.insert(InstFakeUse::create(Func, DestLo)); | 3981 Context.insert(InstFakeUse::create(Func, DestLo)); |
3983 Context.insert(InstFakeUse::create(Func, DestHi)); | 3982 Context.insert(InstFakeUse::create(Func, DestHi)); |
3984 Operand *SrcFLo = loOperand(SrcF); | 3983 Operand *SrcFLo = loOperand(SrcF); |
3985 Operand *SrcFHi = hiOperand(SrcF); | 3984 Operand *SrcFHi = hiOperand(SrcF); |
3986 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); | 3985 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm); |
3987 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); | 3986 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm); |
3988 _mov(DestLo, SrcLoRI); | 3987 _mov(DestLo, SrcLoRI); |
3989 _mov(DestHi, SrcHiRI); | 3988 _mov(DestHi, SrcHiRI); |
3990 } else { | 3989 } else { |
3991 _cmp(ConditionRM, Zero); | 3990 _cmp(ConditionRM, Zero); |
3992 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); | 3991 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm); |
3993 _mov(Dest, SrcT); | 3992 _mov(Dest, SrcT); |
3994 _br(CondX86::Br_ne, Label); | 3993 _br(CondX86::Br_ne, Label); |
3995 Context.insert(InstFakeUse::create(Func, Dest)); | 3994 Context.insert(InstFakeUse::create(Func, Dest)); |
3996 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); | 3995 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm); |
3997 _mov(Dest, SrcF); | 3996 _mov(Dest, SrcF); |
3998 } | 3997 } |
3999 | 3998 |
4000 Context.insert(Label); | 3999 Context.insert(Label); |
4001 } | 4000 } |
4002 | 4001 |
4003 void TargetX8632::lowerStore(const InstStore *Inst) { | 4002 void TargetX8632::lowerStore(const InstStore *Inst) { |
4004 Operand *Value = Inst->getData(); | 4003 Operand *Value = Inst->getData(); |
4005 Operand *Addr = Inst->getAddr(); | 4004 Operand *Addr = Inst->getAddr(); |
4006 OperandX8632Mem *NewAddr = FormMemoryOperand(Addr, Value->getType()); | 4005 OperandX8632Mem *NewAddr = FormMemoryOperand(Addr, Value->getType()); |
4007 Type Ty = NewAddr->getType(); | 4006 Type Ty = NewAddr->getType(); |
4008 | 4007 |
4009 if (Ty == IceType_i64) { | 4008 if (Ty == IceType_i64) { |
4010 Value = legalize(Value); | 4009 Value = legalize(Value); |
4011 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm, true); | 4010 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm); |
4012 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm, true); | 4011 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm); |
4013 _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr))); | 4012 _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr))); |
4014 _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr))); | 4013 _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr))); |
4015 } else if (isVectorType(Ty)) { | 4014 } else if (isVectorType(Ty)) { |
4016 _storep(legalizeToVar(Value), NewAddr); | 4015 _storep(legalizeToVar(Value), NewAddr); |
4017 } else { | 4016 } else { |
4018 Value = legalize(Value, Legal_Reg | Legal_Imm, true); | 4017 Value = legalize(Value, Legal_Reg | Legal_Imm); |
4019 _store(Value, NewAddr); | 4018 _store(Value, NewAddr); |
4020 } | 4019 } |
4021 } | 4020 } |
4022 | 4021 |
4023 void TargetX8632::doAddressOptStore() { | 4022 void TargetX8632::doAddressOptStore() { |
4024 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); | 4023 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); |
4025 Operand *Data = Inst->getData(); | 4024 Operand *Data = Inst->getData(); |
4026 Operand *Addr = Inst->getAddr(); | 4025 Operand *Addr = Inst->getAddr(); |
4027 Variable *Index = NULL; | 4026 Variable *Index = NULL; |
4028 uint16_t Shift = 0; | 4027 uint16_t Shift = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
4047 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { | 4046 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { |
4048 // This implements the most naive possible lowering. | 4047 // This implements the most naive possible lowering. |
4049 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default | 4048 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default |
4050 Operand *Src0 = Inst->getComparison(); | 4049 Operand *Src0 = Inst->getComparison(); |
4051 SizeT NumCases = Inst->getNumCases(); | 4050 SizeT NumCases = Inst->getNumCases(); |
4052 // OK, we'll be slightly less naive by forcing Src into a physical | 4051 // OK, we'll be slightly less naive by forcing Src into a physical |
4053 // register if there are 2 or more uses. | 4052 // register if there are 2 or more uses. |
4054 if (NumCases >= 2) | 4053 if (NumCases >= 2) |
4055 Src0 = legalizeToVar(Src0, true); | 4054 Src0 = legalizeToVar(Src0, true); |
4056 else | 4055 else |
4057 Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true); | 4056 Src0 = legalize(Src0, Legal_Reg | Legal_Mem); |
4058 for (SizeT I = 0; I < NumCases; ++I) { | 4057 for (SizeT I = 0; I < NumCases; ++I) { |
4059 // TODO(stichnot): Correct lowering for IceType_i64. | 4058 // TODO(stichnot): Correct lowering for IceType_i64. |
4060 Constant *Value = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I)); | 4059 Constant *Value = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I)); |
4061 _cmp(Src0, Value); | 4060 _cmp(Src0, Value); |
4062 _br(CondX86::Br_e, Inst->getLabel(I)); | 4061 _br(CondX86::Br_e, Inst->getLabel(I)); |
4063 } | 4062 } |
4064 | 4063 |
4065 _br(Inst->getLabelDefault()); | 4064 _br(Inst->getLabelDefault()); |
4066 } | 4065 } |
4067 | 4066 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4202 Variable *Reg = makeReg(Ty, RegNum); | 4201 Variable *Reg = makeReg(Ty, RegNum); |
4203 if (isVectorType(Ty)) { | 4202 if (isVectorType(Ty)) { |
4204 _movp(Reg, Src); | 4203 _movp(Reg, Src); |
4205 } else { | 4204 } else { |
4206 _mov(Reg, Src); | 4205 _mov(Reg, Src); |
4207 } | 4206 } |
4208 return Reg; | 4207 return Reg; |
4209 } | 4208 } |
4210 | 4209 |
4211 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, | 4210 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
4212 bool AllowOverlap, int32_t RegNum) { | 4211 int32_t RegNum) { |
4213 // Assert that a physical register is allowed. To date, all calls | 4212 // Assert that a physical register is allowed. To date, all calls |
4214 // to legalize() allow a physical register. If a physical register | 4213 // to legalize() allow a physical register. If a physical register |
4215 // needs to be explicitly disallowed, then new code will need to be | 4214 // needs to be explicitly disallowed, then new code will need to be |
4216 // written to force a spill. | 4215 // written to force a spill. |
4217 assert(Allowed & Legal_Reg); | 4216 assert(Allowed & Legal_Reg); |
4218 // If we're asking for a specific physical register, make sure we're | 4217 // If we're asking for a specific physical register, make sure we're |
4219 // not allowing any other operand kinds. (This could be future | 4218 // not allowing any other operand kinds. (This could be future |
4220 // work, e.g. allow the shl shift amount to be either an immediate | 4219 // work, e.g. allow the shl shift amount to be either an immediate |
4221 // or in ecx.) | 4220 // or in ecx.) |
4222 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); | 4221 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); |
4223 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { | 4222 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { |
4224 // Before doing anything with a Mem operand, we need to ensure | 4223 // Before doing anything with a Mem operand, we need to ensure |
4225 // that the Base and Index components are in physical registers. | 4224 // that the Base and Index components are in physical registers. |
4226 Variable *Base = Mem->getBase(); | 4225 Variable *Base = Mem->getBase(); |
4227 Variable *Index = Mem->getIndex(); | 4226 Variable *Index = Mem->getIndex(); |
4228 Variable *RegBase = NULL; | 4227 Variable *RegBase = NULL; |
4229 Variable *RegIndex = NULL; | 4228 Variable *RegIndex = NULL; |
4230 if (Base) { | 4229 if (Base) { |
4231 RegBase = legalizeToVar(Base, true); | 4230 RegBase = legalizeToVar(Base); |
4232 } | 4231 } |
4233 if (Index) { | 4232 if (Index) { |
4234 RegIndex = legalizeToVar(Index, true); | 4233 RegIndex = legalizeToVar(Index); |
4235 } | 4234 } |
4236 if (Base != RegBase || Index != RegIndex) { | 4235 if (Base != RegBase || Index != RegIndex) { |
4237 From = OperandX8632Mem::create( | 4236 From = OperandX8632Mem::create( |
4238 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, | 4237 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, |
4239 Mem->getShift(), Mem->getSegmentRegister()); | 4238 Mem->getShift(), Mem->getSegmentRegister()); |
4240 } | 4239 } |
4241 | 4240 |
4242 if (!(Allowed & Legal_Mem)) { | 4241 if (!(Allowed & Legal_Mem)) { |
4243 From = copyToReg(From, RegNum); | 4242 From = copyToReg(From, RegNum); |
4244 } | 4243 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4286 // can happen either when the variable is pre-colored or when it is | 4285 // can happen either when the variable is pre-colored or when it is |
4287 // assigned infinite weight. | 4286 // assigned infinite weight. |
4288 bool MustHaveRegister = | 4287 bool MustHaveRegister = |
4289 (Var->hasReg() || Var->getWeight() == RegWeight::Inf); | 4288 (Var->hasReg() || Var->getWeight() == RegWeight::Inf); |
4290 // We need a new physical register for the operand if: | 4289 // We need a new physical register for the operand if: |
4291 // Mem is not allowed and Var isn't guaranteed a physical | 4290 // Mem is not allowed and Var isn't guaranteed a physical |
4292 // register, or | 4291 // register, or |
4293 // RegNum is required and Var->getRegNum() doesn't match. | 4292 // RegNum is required and Var->getRegNum() doesn't match. |
4294 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 4293 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
4295 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 4294 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
4296 Variable *Reg = copyToReg(From, RegNum); | 4295 From = copyToReg(From, RegNum); |
4297 if (RegNum == Variable::NoRegister) { | |
4298 Reg->setPreferredRegister(Var, AllowOverlap); | |
4299 } | |
4300 From = Reg; | |
4301 } | 4296 } |
4302 return From; | 4297 return From; |
4303 } | 4298 } |
4304 llvm_unreachable("Unhandled operand kind in legalize()"); | 4299 llvm_unreachable("Unhandled operand kind in legalize()"); |
4305 return From; | 4300 return From; |
4306 } | 4301 } |
4307 | 4302 |
4308 // Provide a trivial wrapper to legalize() for this common usage. | 4303 // Provide a trivial wrapper to legalize() for this common usage. |
4309 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, | 4304 Variable *TargetX8632::legalizeToVar(Operand *From, int32_t RegNum) { |
4310 int32_t RegNum) { | 4305 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
4311 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum)); | |
4312 } | 4306 } |
4313 | 4307 |
4314 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { | 4308 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { |
4315 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); | 4309 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); |
4316 // It may be the case that address mode optimization already creates | 4310 // It may be the case that address mode optimization already creates |
4317 // an OperandX8632Mem, so in that case it wouldn't need another level | 4311 // an OperandX8632Mem, so in that case it wouldn't need another level |
4318 // of transformation. | 4312 // of transformation. |
4319 if (!Mem) { | 4313 if (!Mem) { |
4320 Variable *Base = llvm::dyn_cast<Variable>(Operand); | 4314 Variable *Base = llvm::dyn_cast<Variable>(Operand); |
4321 Constant *Offset = llvm::dyn_cast<Constant>(Operand); | 4315 Constant *Offset = llvm::dyn_cast<Constant>(Operand); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4560 Str << "\t.align\t" << Align << "\n"; | 4554 Str << "\t.align\t" << Align << "\n"; |
4561 Str << MangledName << ":\n"; | 4555 Str << MangledName << ":\n"; |
4562 for (SizeT i = 0; i < Size; ++i) { | 4556 for (SizeT i = 0; i < Size; ++i) { |
4563 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4557 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4564 } | 4558 } |
4565 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4559 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4566 } | 4560 } |
4567 } | 4561 } |
4568 | 4562 |
4569 } // end of namespace Ice | 4563 } // end of namespace Ice |
OLD | NEW |