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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 getRegisterSet(RegSet_CalleeSave, RegSet_None); | 693 getRegisterSet(RegSet_CalleeSave, RegSet_None); |
694 | 694 |
695 size_t GlobalsSize = 0; | 695 size_t GlobalsSize = 0; |
696 std::vector<size_t> LocalsSize(Func->getNumNodes()); | 696 std::vector<size_t> LocalsSize(Func->getNumNodes()); |
697 | 697 |
698 // Prepass. Compute RegsUsed, PreservedRegsSizeBytes, and | 698 // Prepass. Compute RegsUsed, PreservedRegsSizeBytes, and |
699 // SpillAreaSizeBytes. | 699 // SpillAreaSizeBytes. |
700 RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); | 700 RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); |
701 const VarList &Variables = Func->getVariables(); | 701 const VarList &Variables = Func->getVariables(); |
702 const VarList &Args = Func->getArgs(); | 702 const VarList &Args = Func->getArgs(); |
703 VarList SpilledVariables, SortedSpilledVariables, | 703 VarList SpilledVariables, SortedSpilledVariables, VariablesLinkedToSpillSlots; |
704 VariablesLinkedToSpillSplots; | |
705 | 704 |
706 // If there is a separate locals area, this specifies the alignment | 705 // If there is a separate locals area, this specifies the alignment |
707 // for it. | 706 // for it. |
708 uint32_t LocalsSlotsAlignmentBytes = 0; | 707 uint32_t LocalsSlotsAlignmentBytes = 0; |
709 // The entire spill locations area gets aligned to largest natural | 708 // The entire spill locations area gets aligned to largest natural |
710 // alignment of the variables that have a spill slot. | 709 // alignment of the variables that have a spill slot. |
711 uint32_t SpillAreaAlignmentBytes = 0; | 710 uint32_t SpillAreaAlignmentBytes = 0; |
712 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); | 711 for (VarList::const_iterator I = Variables.begin(), E = Variables.end(); |
713 I != E; ++I) { | 712 I != E; ++I) { |
714 Variable *Var = *I; | 713 Variable *Var = *I; |
715 if (Var->hasReg()) { | 714 if (Var->hasReg()) { |
716 RegsUsed[Var->getRegNum()] = true; | 715 RegsUsed[Var->getRegNum()] = true; |
717 continue; | 716 continue; |
718 } | 717 } |
719 // An argument either does not need a stack slot (if passed in a | 718 // An argument either does not need a stack slot (if passed in a |
720 // register) or already has one (if passed on the stack). | 719 // register) or already has one (if passed on the stack). |
721 if (Var->getIsArg()) | 720 if (Var->getIsArg()) |
722 continue; | 721 continue; |
723 // An unreferenced variable doesn't need a stack slot. | 722 // An unreferenced variable doesn't need a stack slot. |
724 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) | 723 if (ComputedLiveRanges && Var->getLiveRange().isEmpty()) |
725 continue; | 724 continue; |
726 // A spill slot linked to a variable with a stack slot should reuse | 725 // A spill slot linked to a variable with a stack slot should reuse |
727 // that stack slot. | 726 // that stack slot. |
728 if (Var->getWeight() == RegWeight::Zero && Var->getRegisterOverlap()) { | 727 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { |
729 if (Variable *Linked = Var->getPreferredRegister()) { | 728 assert(Var->getWeight() == RegWeight::Zero); |
730 if (!Linked->hasReg()) { | 729 if (!SpillVar->getLinkedTo()->hasReg()) { |
731 VariablesLinkedToSpillSplots.push_back(Var); | 730 VariablesLinkedToSpillSlots.push_back(Var); |
732 continue; | 731 continue; |
733 } | |
734 } | 732 } |
735 } | 733 } |
736 SpilledVariables.push_back(Var); | 734 SpilledVariables.push_back(Var); |
737 } | 735 } |
738 | 736 |
739 SortedSpilledVariables.reserve(SpilledVariables.size()); | 737 SortedSpilledVariables.reserve(SpilledVariables.size()); |
740 sortByAlignment(SortedSpilledVariables, SpilledVariables); | 738 sortByAlignment(SortedSpilledVariables, SpilledVariables); |
741 for (VarList::const_iterator I = SortedSpilledVariables.begin(), | 739 for (VarList::const_iterator I = SortedSpilledVariables.begin(), |
742 E = SortedSpilledVariables.end(); | 740 E = SortedSpilledVariables.end(); |
743 I != E; ++I) { | 741 I != E; ++I) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (IsEbpBasedFrame) | 869 if (IsEbpBasedFrame) |
872 Var->setStackOffset(-NextStackOffset); | 870 Var->setStackOffset(-NextStackOffset); |
873 else | 871 else |
874 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); | 872 Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset); |
875 } | 873 } |
876 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; | 874 this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; |
877 this->HasComputedFrame = true; | 875 this->HasComputedFrame = true; |
878 | 876 |
879 // Assign stack offsets to variables that have been linked to spilled | 877 // Assign stack offsets to variables that have been linked to spilled |
880 // variables. | 878 // variables. |
881 for (VarList::const_iterator I = VariablesLinkedToSpillSplots.begin(), | 879 for (VarList::const_iterator I = VariablesLinkedToSpillSlots.begin(), |
882 E = VariablesLinkedToSpillSplots.end(); | 880 E = VariablesLinkedToSpillSlots.end(); |
883 I != E; ++I) { | 881 I != E; ++I) { |
884 Variable *Var = *I; | 882 Variable *Var = *I; |
885 Variable *Linked = Var->getPreferredRegister(); | 883 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); |
886 Var->setStackOffset(Linked->getStackOffset()); | 884 Var->setStackOffset(Linked->getStackOffset()); |
887 } | 885 } |
888 | 886 |
889 if (Func->getContext()->isVerbose(IceV_Frame)) { | 887 if (Func->getContext()->isVerbose(IceV_Frame)) { |
890 Ostream &Str = Func->getContext()->getStrDump(); | 888 Ostream &Str = Func->getContext()->getStrDump(); |
891 | 889 |
892 Str << "Stack layout:\n"; | 890 Str << "Stack layout:\n"; |
893 uint32_t EspAdjustmentPaddingSize = | 891 uint32_t EspAdjustmentPaddingSize = |
894 SpillAreaSizeBytes - LocalsSpillAreaSize - | 892 SpillAreaSizeBytes - LocalsSpillAreaSize - |
895 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; | 893 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 (void)DestType; | 2269 (void)DestType; |
2272 assert((DestType == IceType_i32 && SrcType == IceType_f32) || | 2270 assert((DestType == IceType_i32 && SrcType == IceType_f32) || |
2273 (DestType == IceType_f32 && SrcType == IceType_i32)); | 2271 (DestType == IceType_f32 && SrcType == IceType_i32)); |
2274 // a.i32 = bitcast b.f32 ==> | 2272 // a.i32 = bitcast b.f32 ==> |
2275 // t.f32 = b.f32 | 2273 // t.f32 = b.f32 |
2276 // s.f32 = spill t.f32 | 2274 // s.f32 = spill t.f32 |
2277 // a.i32 = s.f32 | 2275 // a.i32 = s.f32 |
2278 Variable *T = NULL; | 2276 Variable *T = NULL; |
2279 // TODO: Should be able to force a spill setup by calling legalize() with | 2277 // TODO: Should be able to force a spill setup by calling legalize() with |
2280 // Legal_Mem and not Legal_Reg or Legal_Imm. | 2278 // Legal_Mem and not Legal_Reg or Legal_Imm. |
2281 Variable *Spill = Func->makeVariable(SrcType, Context.getNode()); | 2279 SpillVariable *SpillVar = |
| 2280 Func->makeVariable<SpillVariable>(SrcType, Context.getNode()); |
| 2281 SpillVar->setLinkedTo(Dest); |
| 2282 Variable *Spill = SpillVar; |
2282 Spill->setWeight(RegWeight::Zero); | 2283 Spill->setWeight(RegWeight::Zero); |
2283 Spill->setPreferredRegister(Dest, true); | |
2284 _mov(T, Src0RM); | 2284 _mov(T, Src0RM); |
2285 _mov(Spill, T); | 2285 _mov(Spill, T); |
2286 _mov(Dest, Spill); | 2286 _mov(Dest, Spill); |
2287 } break; | 2287 } break; |
2288 case IceType_i64: { | 2288 case IceType_i64: { |
2289 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2289 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
2290 assert(Src0RM->getType() == IceType_f64); | 2290 assert(Src0RM->getType() == IceType_f64); |
2291 // a.i64 = bitcast b.f64 ==> | 2291 // a.i64 = bitcast b.f64 ==> |
2292 // s.f64 = spill b.f64 | 2292 // s.f64 = spill b.f64 |
2293 // t_lo.i32 = lo(s.f64) | 2293 // t_lo.i32 = lo(s.f64) |
2294 // a_lo.i32 = t_lo.i32 | 2294 // a_lo.i32 = t_lo.i32 |
2295 // t_hi.i32 = hi(s.f64) | 2295 // t_hi.i32 = hi(s.f64) |
2296 // a_hi.i32 = t_hi.i32 | 2296 // a_hi.i32 = t_hi.i32 |
2297 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); | 2297 SpillVariable *SpillVar = |
| 2298 Func->makeVariable<SpillVariable>(IceType_f64, Context.getNode()); |
| 2299 SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM)); |
| 2300 Variable *Spill = SpillVar; |
2298 Spill->setWeight(RegWeight::Zero); | 2301 Spill->setWeight(RegWeight::Zero); |
2299 Spill->setPreferredRegister(llvm::dyn_cast<Variable>(Src0RM), true); | |
2300 _movq(Spill, Src0RM); | 2302 _movq(Spill, Src0RM); |
2301 | 2303 |
2302 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2304 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2303 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2305 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2304 Variable *T_Lo = makeReg(IceType_i32); | 2306 Variable *T_Lo = makeReg(IceType_i32); |
2305 Variable *T_Hi = makeReg(IceType_i32); | 2307 Variable *T_Hi = makeReg(IceType_i32); |
2306 VariableSplit *SpillLo = | 2308 VariableSplit *SpillLo = |
2307 VariableSplit::create(Func, Spill, VariableSplit::Low); | 2309 VariableSplit::create(Func, Spill, VariableSplit::Low); |
2308 VariableSplit *SpillHi = | 2310 VariableSplit *SpillHi = |
2309 VariableSplit::create(Func, Spill, VariableSplit::High); | 2311 VariableSplit::create(Func, Spill, VariableSplit::High); |
2310 | 2312 |
2311 _mov(T_Lo, SpillLo); | 2313 _mov(T_Lo, SpillLo); |
2312 _mov(DestLo, T_Lo); | 2314 _mov(DestLo, T_Lo); |
2313 _mov(T_Hi, SpillHi); | 2315 _mov(T_Hi, SpillHi); |
2314 _mov(DestHi, T_Hi); | 2316 _mov(DestHi, T_Hi); |
2315 } break; | 2317 } break; |
2316 case IceType_f64: { | 2318 case IceType_f64: { |
2317 Src0 = legalize(Src0); | 2319 Src0 = legalize(Src0); |
2318 assert(Src0->getType() == IceType_i64); | 2320 assert(Src0->getType() == IceType_i64); |
2319 // a.f64 = bitcast b.i64 ==> | 2321 // a.f64 = bitcast b.i64 ==> |
2320 // t_lo.i32 = b_lo.i32 | 2322 // t_lo.i32 = b_lo.i32 |
2321 // FakeDef(s.f64) | 2323 // FakeDef(s.f64) |
2322 // lo(s.f64) = t_lo.i32 | 2324 // lo(s.f64) = t_lo.i32 |
2323 // t_hi.i32 = b_hi.i32 | 2325 // t_hi.i32 = b_hi.i32 |
2324 // hi(s.f64) = t_hi.i32 | 2326 // hi(s.f64) = t_hi.i32 |
2325 // a.f64 = s.f64 | 2327 // a.f64 = s.f64 |
2326 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); | 2328 SpillVariable *SpillVar = |
| 2329 Func->makeVariable<SpillVariable>(IceType_f64, Context.getNode()); |
| 2330 SpillVar->setLinkedTo(Dest); |
| 2331 Variable *Spill = SpillVar; |
2327 Spill->setWeight(RegWeight::Zero); | 2332 Spill->setWeight(RegWeight::Zero); |
2328 Spill->setPreferredRegister(Dest, true); | |
2329 | 2333 |
2330 Variable *T_Lo = NULL, *T_Hi = NULL; | 2334 Variable *T_Lo = NULL, *T_Hi = NULL; |
2331 VariableSplit *SpillLo = | 2335 VariableSplit *SpillLo = |
2332 VariableSplit::create(Func, Spill, VariableSplit::Low); | 2336 VariableSplit::create(Func, Spill, VariableSplit::Low); |
2333 VariableSplit *SpillHi = | 2337 VariableSplit *SpillHi = |
2334 VariableSplit::create(Func, Spill, VariableSplit::High); | 2338 VariableSplit::create(Func, Spill, VariableSplit::High); |
2335 _mov(T_Lo, loOperand(Src0)); | 2339 _mov(T_Lo, loOperand(Src0)); |
2336 // Technically, the Spill is defined after the _store happens, but | 2340 // Technically, the Spill is defined after the _store happens, but |
2337 // SpillLo is considered a "use" of Spill so define Spill before it | 2341 // SpillLo is considered a "use" of Spill so define Spill before it |
2338 // is used. | 2342 // is used. |
(...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3713 Base = Var; | 3717 Base = Var; |
3714 Offset += MoreOffset; | 3718 Offset += MoreOffset; |
3715 Reason = BaseInst; | 3719 Reason = BaseInst; |
3716 return true; | 3720 return true; |
3717 } | 3721 } |
3718 return false; | 3722 return false; |
3719 } | 3723 } |
3720 | 3724 |
3721 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, | 3725 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, |
3722 Variable *&Index, uint16_t &Shift, int32_t &Offset) { | 3726 Variable *&Index, uint16_t &Shift, int32_t &Offset) { |
3723 Func->setCurrentNode(NULL); | 3727 Func->resetCurrentNode(); |
3724 if (Func->getContext()->isVerbose(IceV_AddrOpt)) { | 3728 if (Func->getContext()->isVerbose(IceV_AddrOpt)) { |
3725 Ostream &Str = Func->getContext()->getStrDump(); | 3729 Ostream &Str = Func->getContext()->getStrDump(); |
3726 Str << "\nStarting computeAddressOpt for instruction:\n "; | 3730 Str << "\nStarting computeAddressOpt for instruction:\n "; |
3727 Instr->dumpDecorated(Func); | 3731 Instr->dumpDecorated(Func); |
3728 } | 3732 } |
3729 (void)Offset; // TODO: pattern-match for non-zero offsets. | 3733 (void)Offset; // TODO: pattern-match for non-zero offsets. |
3730 if (Base == NULL) | 3734 if (Base == NULL) |
3731 return; | 3735 return; |
3732 // If the Base has more than one use or is live across multiple | 3736 // If the Base has more than one use or is live across multiple |
3733 // blocks, then don't go further. Alternatively (?), never consider | 3737 // blocks, then don't go further. Alternatively (?), never consider |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4548 Str << "\t.align\t" << Align << "\n"; | 4552 Str << "\t.align\t" << Align << "\n"; |
4549 Str << MangledName << ":\n"; | 4553 Str << MangledName << ":\n"; |
4550 for (SizeT i = 0; i < Size; ++i) { | 4554 for (SizeT i = 0; i < Size; ++i) { |
4551 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4555 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4552 } | 4556 } |
4553 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4557 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4554 } | 4558 } |
4555 } | 4559 } |
4556 | 4560 |
4557 } // end of namespace Ice | 4561 } // end of namespace Ice |
OLD | NEW |