Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1141213004: Subzero: Fold icmp into br/select lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Remove unnecessary break statement Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698