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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // entries in case the high-level table has extra entries. | 253 // entries in case the high-level table has extra entries. |
254 #define X(tag, size, align, elts, elty, str) \ | 254 #define X(tag, size, align, elts, elty, str) \ |
255 static_assert(_table1_##tag == _table2_##tag, \ | 255 static_assert(_table1_##tag == _table2_##tag, \ |
256 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 256 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
257 ICETYPE_TABLE | 257 ICETYPE_TABLE |
258 #undef X | 258 #undef X |
259 } // end of namespace dummy3 | 259 } // end of namespace dummy3 |
260 | 260 |
261 } // end of anonymous namespace | 261 } // end of anonymous namespace |
262 | 262 |
| 263 BoolFoldingEntry::BoolFoldingEntry(Inst *I) |
| 264 : Instr(I), IsComplex(BoolFolding::hasComplexLowering(I)), IsLiveOut(true), |
| 265 NumUses(0) {} |
| 266 |
| 267 BoolFolding::BoolFoldingProducerKind |
| 268 BoolFolding::getProducerKind(const Inst *Instr) { |
| 269 if (llvm::isa<InstIcmp>(Instr)) { |
| 270 if (Instr->getSrc(0)->getType() != IceType_i64) |
| 271 return PK_Icmp32; |
| 272 return PK_None; // TODO(stichnot): actually PK_Icmp64; |
| 273 } |
| 274 return PK_None; // TODO(stichnot): remove this |
| 275 |
| 276 if (llvm::isa<InstFcmp>(Instr)) |
| 277 return PK_Fcmp; |
| 278 if (auto *Cast = llvm::dyn_cast<InstCast>(Instr)) { |
| 279 switch (Cast->getCastKind()) { |
| 280 default: |
| 281 return PK_None; |
| 282 case InstCast::Trunc: |
| 283 return PK_Trunc; |
| 284 } |
| 285 } |
| 286 return PK_None; |
| 287 } |
| 288 |
| 289 BoolFolding::BoolFoldingConsumerKind |
| 290 BoolFolding::getConsumerKind(const Inst *Instr) { |
| 291 if (llvm::isa<InstBr>(Instr)) |
| 292 return CK_Br; |
| 293 if (llvm::isa<InstSelect>(Instr)) |
| 294 return CK_Select; |
| 295 return CK_None; // TODO(stichnot): remove this |
| 296 |
| 297 if (auto *Cast = llvm::dyn_cast<InstCast>(Instr)) { |
| 298 switch (Cast->getCastKind()) { |
| 299 default: |
| 300 return CK_None; |
| 301 case InstCast::Sext: |
| 302 return CK_Sext; |
| 303 case InstCast::Zext: |
| 304 return CK_Zext; |
| 305 } |
| 306 } |
| 307 return CK_None; |
| 308 } |
| 309 |
| 310 // Returns true if the producing instruction has a "complex" lowering |
| 311 // sequence. This generally means that its lowering sequence requires |
| 312 // more than one conditional branch, namely 64-bit integer compares |
| 313 // and some floating-point compares. When this is true, and there is |
| 314 // more than one consumer, we prefer to disable the folding |
| 315 // optimization because it minimizes branches. |
| 316 bool BoolFolding::hasComplexLowering(const Inst *Instr) { |
| 317 switch (getProducerKind(Instr)) { |
| 318 default: |
| 319 return false; |
| 320 case PK_Icmp64: |
| 321 return true; |
| 322 case PK_Fcmp: |
| 323 return TableFcmp[llvm::cast<InstFcmp>(Instr)->getCondition()].C2 != |
| 324 CondX86::Br_None; |
| 325 } |
| 326 } |
| 327 |
| 328 void BoolFolding::init(CfgNode *Node) { |
| 329 Producers.clear(); |
| 330 for (Inst &Instr : Node->getInsts()) { |
| 331 // Check whether Instr is a valid producer. |
| 332 Variable *Var = Instr.getDest(); |
| 333 if (!Instr.isDeleted() // only consider non-deleted instructions |
| 334 && Var // only instructions with an actual dest var |
| 335 && Var->getType() == IceType_i1 // only bool-type dest vars |
| 336 && getProducerKind(&Instr) != PK_None) { // white-listed instructions |
| 337 Producers[Var->getIndex()] = BoolFoldingEntry(&Instr); |
| 338 } |
| 339 // Check each src variable against the map. |
| 340 for (SizeT I = 0; I < Instr.getSrcSize(); ++I) { |
| 341 Operand *Src = Instr.getSrc(I); |
| 342 SizeT NumVars = Src->getNumVars(); |
| 343 for (SizeT J = 0; J < NumVars; ++J) { |
| 344 const Variable *Var = Src->getVar(J); |
| 345 SizeT VarNum = Var->getIndex(); |
| 346 if (containsValid(VarNum)) { |
| 347 if (I != 0 // All valid consumers use Var as the first source operand |
| 348 || getConsumerKind(&Instr) == CK_None // must be white-listed |
| 349 || (Producers[VarNum].IsComplex && // complex can't be multi-use |
| 350 Producers[VarNum].NumUses > 0)) { |
| 351 setInvalid(VarNum); |
| 352 continue; |
| 353 } |
| 354 ++Producers[VarNum].NumUses; |
| 355 if (Instr.isLastUse(Var)) { |
| 356 Producers[VarNum].IsLiveOut = false; |
| 357 } |
| 358 } |
| 359 } |
| 360 } |
| 361 } |
| 362 for (auto &I : Producers) { |
| 363 // Ignore entries previously marked invalid. |
| 364 if (I.second.Instr == nullptr) |
| 365 continue; |
| 366 // Disable the producer if its dest may be live beyond this block. |
| 367 if (I.second.IsLiveOut) { |
| 368 setInvalid(I.first); |
| 369 continue; |
| 370 } |
| 371 // Mark as "dead" rather than outright deleting. This is so that |
| 372 // other peephole style optimizations during or before lowering |
| 373 // have access to this instruction in undeleted form. See for |
| 374 // example tryOptimizedCmpxchgCmpBr(). |
| 375 I.second.Instr->setDead(); |
| 376 } |
| 377 } |
| 378 |
| 379 const Inst *BoolFolding::getProducerFor(const Operand *Opnd) const { |
| 380 auto *Var = llvm::dyn_cast<const Variable>(Opnd); |
| 381 if (Var == nullptr) |
| 382 return nullptr; |
| 383 SizeT VarNum = Var->getIndex(); |
| 384 auto Element = Producers.find(VarNum); |
| 385 if (Element == Producers.end()) |
| 386 return nullptr; |
| 387 return Element->second.Instr; |
| 388 } |
| 389 |
| 390 void BoolFolding::dump(const Cfg *Func) const { |
| 391 if (!ALLOW_DUMP || !Func->isVerbose(IceV_Folding)) |
| 392 return; |
| 393 OstreamLocker L(Func->getContext()); |
| 394 Ostream &Str = Func->getContext()->getStrDump(); |
| 395 for (auto &I : Producers) { |
| 396 if (I.second.Instr == nullptr) |
| 397 continue; |
| 398 Str << "Found foldable producer:\n "; |
| 399 I.second.Instr->dump(Func); |
| 400 Str << "\n"; |
| 401 } |
| 402 } |
| 403 |
| 404 void TargetX8632::initNodeForLowering(CfgNode *Node) { |
| 405 FoldingInfo.init(Node); |
| 406 FoldingInfo.dump(Func); |
| 407 } |
| 408 |
263 TargetX8632::TargetX8632(Cfg *Func) | 409 TargetX8632::TargetX8632(Cfg *Func) |
264 : TargetLowering(Func), | 410 : TargetLowering(Func), |
265 InstructionSet(static_cast<X86InstructionSet>( | 411 InstructionSet(static_cast<X86InstructionSet>( |
266 Func->getContext()->getFlags().getTargetInstructionSet() - | 412 Func->getContext()->getFlags().getTargetInstructionSet() - |
267 TargetInstructionSet::X86InstructionSet_Begin)), | 413 TargetInstructionSet::X86InstructionSet_Begin)), |
268 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0), | 414 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0), |
269 SpillAreaSizeBytes(0) { | 415 SpillAreaSizeBytes(0) { |
270 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) == | 416 static_assert((X86InstructionSet::End - X86InstructionSet::Begin) == |
271 (TargetInstructionSet::X86InstructionSet_End - | 417 (TargetInstructionSet::X86InstructionSet_End - |
272 TargetInstructionSet::X86InstructionSet_Begin), | 418 TargetInstructionSet::X86InstructionSet_Begin), |
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1712 if (isVectorType(Dest->getType())) | 1858 if (isVectorType(Dest->getType())) |
1713 _movp(Dest, RI); | 1859 _movp(Dest, RI); |
1714 else | 1860 else |
1715 _mov(Dest, RI); | 1861 _mov(Dest, RI); |
1716 } | 1862 } |
1717 } | 1863 } |
1718 | 1864 |
1719 void TargetX8632::lowerBr(const InstBr *Inst) { | 1865 void TargetX8632::lowerBr(const InstBr *Inst) { |
1720 if (Inst->isUnconditional()) { | 1866 if (Inst->isUnconditional()) { |
1721 _br(Inst->getTargetUnconditional()); | 1867 _br(Inst->getTargetUnconditional()); |
1722 } else { | 1868 return; |
1723 Operand *Src0 = legalize(Inst->getCondition(), Legal_Reg | Legal_Mem); | |
1724 Constant *Zero = Ctx->getConstantZero(IceType_i32); | |
1725 _cmp(Src0, Zero); | |
1726 _br(CondX86::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse()); | |
1727 } | 1869 } |
| 1870 Operand *Cond = Inst->getCondition(); |
| 1871 |
| 1872 // Handle folding opportunities. |
| 1873 if (const class Inst *Producer = FoldingInfo.getProducerFor(Cond)) { |
| 1874 assert(Producer->isDeleted()); |
| 1875 switch (BoolFolding::getProducerKind(Producer)) { |
| 1876 default: |
| 1877 break; |
| 1878 case BoolFolding::PK_Icmp32: { |
| 1879 // TODO(stichnot): Refactor similarities between this block and |
| 1880 // the corresponding code in lowerIcmp(). |
| 1881 auto *Cmp = llvm::dyn_cast<InstIcmp>(Producer); |
| 1882 Operand *Src0 = Producer->getSrc(0); |
| 1883 Operand *Src1 = legalize(Producer->getSrc(1)); |
| 1884 Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1); |
| 1885 _cmp(Src0RM, Src1); |
| 1886 _br(getIcmp32Mapping(Cmp->getCondition()), Inst->getTargetTrue(), |
| 1887 Inst->getTargetFalse()); |
| 1888 return; |
| 1889 } |
| 1890 } |
| 1891 } |
| 1892 |
| 1893 Operand *Src0 = legalize(Cond, Legal_Reg | Legal_Mem); |
| 1894 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1895 _cmp(Src0, Zero); |
| 1896 _br(CondX86::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse()); |
1728 } | 1897 } |
1729 | 1898 |
1730 void TargetX8632::lowerCall(const InstCall *Instr) { | 1899 void TargetX8632::lowerCall(const InstCall *Instr) { |
1731 // x86-32 calling convention: | 1900 // x86-32 calling convention: |
1732 // | 1901 // |
1733 // * At the point before the call, the stack must be aligned to 16 | 1902 // * At the point before the call, the stack must be aligned to 16 |
1734 // bytes. | 1903 // bytes. |
1735 // | 1904 // |
1736 // * The first four arguments of vector type, regardless of their | 1905 // * The first four arguments of vector type, regardless of their |
1737 // position relative to the other arguments in the argument list, are | 1906 // position relative to the other arguments in the argument list, are |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2671 Variable *MinusOne = makeVectorOfMinusOnes(Ty); | 2840 Variable *MinusOne = makeVectorOfMinusOnes(Ty); |
2672 _pxor(T, MinusOne); | 2841 _pxor(T, MinusOne); |
2673 } break; | 2842 } break; |
2674 } | 2843 } |
2675 | 2844 |
2676 _movp(Dest, T); | 2845 _movp(Dest, T); |
2677 eliminateNextVectorSextInstruction(Dest); | 2846 eliminateNextVectorSextInstruction(Dest); |
2678 return; | 2847 return; |
2679 } | 2848 } |
2680 | 2849 |
2681 // If Src1 is an immediate, or known to be a physical register, we can | |
2682 // allow Src0 to be a memory operand. Otherwise, Src0 must be copied into | |
2683 // a physical register. (Actually, either Src0 or Src1 can be chosen for | |
2684 // the physical register, but unfortunately we have to commit to one or | |
2685 // the other before register allocation.) | |
2686 bool IsSrc1ImmOrReg = false; | |
2687 if (llvm::isa<Constant>(Src1)) { | |
2688 IsSrc1ImmOrReg = true; | |
2689 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { | |
2690 if (Var->hasReg()) | |
2691 IsSrc1ImmOrReg = true; | |
2692 } | |
2693 | |
2694 // Try to fuse a compare immediately followed by a conditional branch. This | |
2695 // is possible when the compare dest and the branch source operands are the | |
2696 // same, and are their only uses. TODO: implement this optimization for i64. | |
2697 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { | |
2698 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && | |
2699 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { | |
2700 NextBr->setDeleted(); | |
2701 Operand *Src0RM = | |
2702 legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); | |
2703 _cmp(Src0RM, Src1); | |
2704 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), | |
2705 NextBr->getTargetFalse()); | |
2706 // Skip over the following branch instruction. | |
2707 Context.advanceNext(); | |
2708 return; | |
2709 } | |
2710 } | |
2711 | |
2712 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: | 2850 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: |
2713 if (Src0->getType() == IceType_i64) { | 2851 if (Src0->getType() == IceType_i64) { |
2714 InstIcmp::ICond Condition = Inst->getCondition(); | 2852 InstIcmp::ICond Condition = Inst->getCondition(); |
2715 size_t Index = static_cast<size_t>(Condition); | 2853 size_t Index = static_cast<size_t>(Condition); |
2716 assert(Index < TableIcmp64Size); | 2854 assert(Index < TableIcmp64Size); |
2717 Operand *Src0LoRM = legalize(loOperand(Src0), Legal_Reg | Legal_Mem); | 2855 Operand *Src0LoRM = legalize(loOperand(Src0), Legal_Reg | Legal_Mem); |
2718 Operand *Src0HiRM = legalize(hiOperand(Src0), Legal_Reg | Legal_Mem); | 2856 Operand *Src0HiRM = legalize(hiOperand(Src0), Legal_Reg | Legal_Mem); |
2719 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); | 2857 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); |
2720 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); | 2858 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); |
2721 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 2859 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
2722 Constant *One = Ctx->getConstantInt32(1); | 2860 Constant *One = Ctx->getConstantInt32(1); |
2723 InstX8632Label *LabelFalse = InstX8632Label::create(Func, this); | 2861 InstX8632Label *LabelFalse = InstX8632Label::create(Func, this); |
2724 InstX8632Label *LabelTrue = InstX8632Label::create(Func, this); | 2862 InstX8632Label *LabelTrue = InstX8632Label::create(Func, this); |
2725 _mov(Dest, One); | 2863 _mov(Dest, One); |
2726 _cmp(Src0HiRM, Src1HiRI); | 2864 _cmp(Src0HiRM, Src1HiRI); |
2727 if (TableIcmp64[Index].C1 != CondX86::Br_None) | 2865 if (TableIcmp64[Index].C1 != CondX86::Br_None) |
2728 _br(TableIcmp64[Index].C1, LabelTrue); | 2866 _br(TableIcmp64[Index].C1, LabelTrue); |
2729 if (TableIcmp64[Index].C2 != CondX86::Br_None) | 2867 if (TableIcmp64[Index].C2 != CondX86::Br_None) |
2730 _br(TableIcmp64[Index].C2, LabelFalse); | 2868 _br(TableIcmp64[Index].C2, LabelFalse); |
2731 _cmp(Src0LoRM, Src1LoRI); | 2869 _cmp(Src0LoRM, Src1LoRI); |
2732 _br(TableIcmp64[Index].C3, LabelTrue); | 2870 _br(TableIcmp64[Index].C3, LabelTrue); |
2733 Context.insert(LabelFalse); | 2871 Context.insert(LabelFalse); |
2734 _mov_nonkillable(Dest, Zero); | 2872 _mov_nonkillable(Dest, Zero); |
2735 Context.insert(LabelTrue); | 2873 Context.insert(LabelTrue); |
2736 return; | 2874 return; |
2737 } | 2875 } |
2738 | 2876 |
2739 // cmp b, c | 2877 // cmp b, c |
2740 Operand *Src0RM = | 2878 Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1); |
2741 legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); | |
2742 _cmp(Src0RM, Src1); | 2879 _cmp(Src0RM, Src1); |
2743 _setcc(Dest, getIcmp32Mapping(Inst->getCondition())); | 2880 _setcc(Dest, getIcmp32Mapping(Inst->getCondition())); |
2744 } | 2881 } |
2745 | 2882 |
2746 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { | 2883 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
2747 Operand *SourceVectNotLegalized = Inst->getSrc(0); | 2884 Operand *SourceVectNotLegalized = Inst->getSrc(0); |
2748 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); | 2885 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); |
2749 ConstantInteger32 *ElementIndex = | 2886 ConstantInteger32 *ElementIndex = |
2750 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2)); | 2887 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2)); |
2751 // Only constant indices are allowed in PNaCl IR. | 2888 // Only constant indices are allowed in PNaCl IR. |
(...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3994 } | 4131 } |
3995 _movp(T2, T); | 4132 _movp(T2, T); |
3996 _pand(T, SrcTRM); | 4133 _pand(T, SrcTRM); |
3997 _pandn(T2, SrcFRM); | 4134 _pandn(T2, SrcFRM); |
3998 _por(T, T2); | 4135 _por(T, T2); |
3999 _movp(Dest, T); | 4136 _movp(Dest, T); |
4000 | 4137 |
4001 return; | 4138 return; |
4002 } | 4139 } |
4003 | 4140 |
4004 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: | 4141 // Handle folding opportunities. |
| 4142 if (const class Inst *Producer = FoldingInfo.getProducerFor(Condition)) { |
| 4143 assert(Producer->isDeleted()); |
| 4144 switch (BoolFolding::getProducerKind(Producer)) { |
| 4145 default: |
| 4146 break; |
| 4147 case BoolFolding::PK_Icmp32: { |
| 4148 // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1: |
| 4149 auto *Cmp = llvm::dyn_cast<InstIcmp>(Producer); |
| 4150 InstX8632Label *Label = InstX8632Label::create(Func, this); |
| 4151 Operand *Src0 = Producer->getSrc(0); |
| 4152 Operand *Src1 = legalize(Producer->getSrc(1)); |
| 4153 Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1); |
| 4154 _cmp(Src0RM, Src1); |
| 4155 // This is the same code as below (for both i64 and non-i64), |
| 4156 // except without the _cmp instruction and with a different |
| 4157 // branch condition. TODO(stichnot): refactor. |
| 4158 if (Dest->getType() == IceType_i64) { |
| 4159 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 4160 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 4161 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm); |
| 4162 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm); |
| 4163 _mov(DestLo, SrcLoRI); |
| 4164 _mov(DestHi, SrcHiRI); |
| 4165 _br(getIcmp32Mapping(Cmp->getCondition()), Label); |
| 4166 Operand *SrcFLo = loOperand(SrcF); |
| 4167 Operand *SrcFHi = hiOperand(SrcF); |
| 4168 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm); |
| 4169 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm); |
| 4170 _mov_nonkillable(DestLo, SrcLoRI); |
| 4171 _mov_nonkillable(DestHi, SrcHiRI); |
| 4172 } else { |
| 4173 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm); |
| 4174 _mov(Dest, SrcT); |
| 4175 _br(getIcmp32Mapping(Cmp->getCondition()), Label); |
| 4176 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm); |
| 4177 _mov_nonkillable(Dest, SrcF); |
| 4178 } |
| 4179 Context.insert(Label); |
| 4180 return; |
| 4181 } |
| 4182 } |
| 4183 } |
| 4184 |
| 4185 // a=d?b:c ==> cmp d,0; a=b; jne L1; a=c; L1: |
4005 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); | 4186 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); |
4006 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 4187 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
4007 InstX8632Label *Label = InstX8632Label::create(Func, this); | 4188 InstX8632Label *Label = InstX8632Label::create(Func, this); |
4008 | 4189 |
4009 if (Dest->getType() == IceType_i64) { | 4190 if (Dest->getType() == IceType_i64) { |
4010 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 4191 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
4011 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 4192 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
4012 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm); | 4193 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm); |
4013 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm); | 4194 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm); |
4014 _cmp(ConditionRM, Zero); | 4195 _cmp(ConditionRM, Zero); |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4527 } | 4708 } |
4528 llvm_unreachable("Unhandled operand kind in legalize()"); | 4709 llvm_unreachable("Unhandled operand kind in legalize()"); |
4529 return From; | 4710 return From; |
4530 } | 4711 } |
4531 | 4712 |
4532 // Provide a trivial wrapper to legalize() for this common usage. | 4713 // Provide a trivial wrapper to legalize() for this common usage. |
4533 Variable *TargetX8632::legalizeToVar(Operand *From, int32_t RegNum) { | 4714 Variable *TargetX8632::legalizeToVar(Operand *From, int32_t RegNum) { |
4534 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); | 4715 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
4535 } | 4716 } |
4536 | 4717 |
| 4718 // For the cmp instruction, if Src1 is an immediate, or known to be a |
| 4719 // physical register, we can allow Src0 to be a memory operand. |
| 4720 // Otherwise, Src0 must be copied into a physical register. |
| 4721 // (Actually, either Src0 or Src1 can be chosen for the physical |
| 4722 // register, but unfortunately we have to commit to one or the other |
| 4723 // before register allocation.) |
| 4724 Operand *TargetX8632::legalizeSrc0ForCmp(Operand *Src0, Operand *Src1) { |
| 4725 bool IsSrc1ImmOrReg = false; |
| 4726 if (llvm::isa<Constant>(Src1)) { |
| 4727 IsSrc1ImmOrReg = true; |
| 4728 } else if (Variable *Var = llvm::dyn_cast<Variable>(Src1)) { |
| 4729 if (Var->hasReg()) |
| 4730 IsSrc1ImmOrReg = true; |
| 4731 } |
| 4732 return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg); |
| 4733 } |
| 4734 |
4537 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { | 4735 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { |
4538 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); | 4736 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); |
4539 // It may be the case that address mode optimization already creates | 4737 // It may be the case that address mode optimization already creates |
4540 // an OperandX8632Mem, so in that case it wouldn't need another level | 4738 // an OperandX8632Mem, so in that case it wouldn't need another level |
4541 // of transformation. | 4739 // of transformation. |
4542 if (!Mem) { | 4740 if (!Mem) { |
4543 Variable *Base = llvm::dyn_cast<Variable>(Operand); | 4741 Variable *Base = llvm::dyn_cast<Variable>(Operand); |
4544 Constant *Offset = llvm::dyn_cast<Constant>(Operand); | 4742 Constant *Offset = llvm::dyn_cast<Constant>(Operand); |
4545 assert(Base || Offset); | 4743 assert(Base || Offset); |
4546 if (Offset) { | 4744 if (Offset) { |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4849 case FT_Asm: | 5047 case FT_Asm: |
4850 case FT_Iasm: { | 5048 case FT_Iasm: { |
4851 OstreamLocker L(Ctx); | 5049 OstreamLocker L(Ctx); |
4852 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 5050 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
4853 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 5051 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
4854 } break; | 5052 } break; |
4855 } | 5053 } |
4856 } | 5054 } |
4857 | 5055 |
4858 } // end of namespace Ice | 5056 } // end of namespace Ice |
OLD | NEW |