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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 586943003: Subzero: Change the way bitcast stack slot lowering is handled. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Add clarifying comment to asType() Created 6 years, 3 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
« no previous file with comments | « src/IceRegAlloc.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceRegAlloc.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698