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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1312433004: Weight variables by their number of uses for register allocation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Count uses in VMetadata Created 5 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
OLDNEW
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 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 /// \file 10 /// \file
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 403 }
404 404
405 void TargetARM32::emitVariable(const Variable *Var) const { 405 void TargetARM32::emitVariable(const Variable *Var) const {
406 if (!BuildDefs::dump()) 406 if (!BuildDefs::dump())
407 return; 407 return;
408 Ostream &Str = Ctx->getStrEmit(); 408 Ostream &Str = Ctx->getStrEmit();
409 if (Var->hasReg()) { 409 if (Var->hasReg()) {
410 Str << getRegName(Var->getRegNum(), Var->getType()); 410 Str << getRegName(Var->getRegNum(), Var->getType());
411 return; 411 return;
412 } 412 }
413 if (Var->getWeight().isInf()) { 413 if (Var->mustHaveReg()) {
414 llvm::report_fatal_error( 414 llvm::report_fatal_error(
415 "Infinite-weight Variable has no register assigned"); 415 "Infinite-weight Variable has no register assigned");
416 } 416 }
417 int32_t Offset = Var->getStackOffset(); 417 int32_t Offset = Var->getStackOffset();
418 int32_t BaseRegNum = Var->getBaseRegNum(); 418 int32_t BaseRegNum = Var->getBaseRegNum();
419 if (BaseRegNum == Variable::NoRegister) { 419 if (BaseRegNum == Variable::NoRegister) {
420 BaseRegNum = getFrameOrStackReg(); 420 BaseRegNum = getFrameOrStackReg();
421 if (!hasFramePointer()) 421 if (!hasFramePointer())
422 Offset += getStackAdjustment(); 422 Offset += getStackAdjustment();
423 } 423 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 if (ShouldSub) 900 if (ShouldSub)
901 Offset = -Offset; 901 Offset = -Offset;
902 Operand *OffsetVal = legalize(Ctx->getConstantInt32(Offset), 902 Operand *OffsetVal = legalize(Ctx->getConstantInt32(Offset),
903 Legal_Reg | Legal_Flex, getReservedTmpReg()); 903 Legal_Reg | Legal_Flex, getReservedTmpReg());
904 Variable *ScratchReg = makeReg(IceType_i32, getReservedTmpReg()); 904 Variable *ScratchReg = makeReg(IceType_i32, getReservedTmpReg());
905 if (ShouldSub) 905 if (ShouldSub)
906 _sub(ScratchReg, OrigBaseReg, OffsetVal); 906 _sub(ScratchReg, OrigBaseReg, OffsetVal);
907 else 907 else
908 _add(ScratchReg, OrigBaseReg, OffsetVal); 908 _add(ScratchReg, OrigBaseReg, OffsetVal);
909 StackVariable *NewVar = Func->makeVariable<StackVariable>(stackSlotType()); 909 StackVariable *NewVar = Func->makeVariable<StackVariable>(stackSlotType());
910 NewVar->setWeight(RegWeight::Zero); 910 NewVar->setMustNotHaveReg();
911 NewVar->setBaseRegNum(ScratchReg->getRegNum()); 911 NewVar->setBaseRegNum(ScratchReg->getRegNum());
912 constexpr int32_t NewOffset = 0; 912 constexpr int32_t NewOffset = 0;
913 NewVar->setStackOffset(NewOffset); 913 NewVar->setStackOffset(NewOffset);
914 return NewVar; 914 return NewVar;
915 } 915 }
916 916
917 void TargetARM32::legalizeStackSlots() { 917 void TargetARM32::legalizeStackSlots() {
918 // If a stack variable's frame offset doesn't fit, convert from: 918 // If a stack variable's frame offset doesn't fit, convert from:
919 // ldr X, OFF[SP] 919 // ldr X, OFF[SP]
920 // to: 920 // to:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 } 977 }
978 if (!Dest->hasReg()) { 978 if (!Dest->hasReg()) {
979 int32_t Offset = Dest->getStackOffset(); 979 int32_t Offset = Dest->getStackOffset();
980 Offset += StackAdjust; 980 Offset += StackAdjust;
981 if (!isLegalVariableStackOffset(Offset)) { 981 if (!isLegalVariableStackOffset(Offset)) {
982 if (NewBaseReg) { 982 if (NewBaseReg) {
983 int32_t OffsetDiff = Offset - NewBaseOffset; 983 int32_t OffsetDiff = Offset - NewBaseOffset;
984 if (isLegalVariableStackOffset(OffsetDiff)) { 984 if (isLegalVariableStackOffset(OffsetDiff)) {
985 StackVariable *NewDest = 985 StackVariable *NewDest =
986 Func->makeVariable<StackVariable>(stackSlotType()); 986 Func->makeVariable<StackVariable>(stackSlotType());
987 NewDest->setWeight(RegWeight::Zero); 987 NewDest->setMustNotHaveReg();
988 NewDest->setBaseRegNum(NewBaseReg->getBaseRegNum()); 988 NewDest->setBaseRegNum(NewBaseReg->getBaseRegNum());
989 NewDest->setStackOffset(OffsetDiff); 989 NewDest->setStackOffset(OffsetDiff);
990 Variable *NewDestVar = NewDest; 990 Variable *NewDestVar = NewDest;
991 _mov(NewDestVar, MovInst->getSrc(0)); 991 _mov(NewDestVar, MovInst->getSrc(0));
992 MovInst->setDeleted(); 992 MovInst->setDeleted();
993 continue; 993 continue;
994 } 994 }
995 } 995 }
996 StackVariable *LegalDest = legalizeVariableSlot(Dest, OrigBaseReg); 996 StackVariable *LegalDest = legalizeVariableSlot(Dest, OrigBaseReg);
997 assert(LegalDest != Dest); 997 assert(LegalDest != Dest);
998 Variable *LegalDestVar = LegalDest; 998 Variable *LegalDestVar = LegalDest;
999 _mov(LegalDestVar, MovInst->getSrc(0)); 999 _mov(LegalDestVar, MovInst->getSrc(0));
1000 MovInst->setDeleted(); 1000 MovInst->setDeleted();
1001 NewBaseReg = LegalDest; 1001 NewBaseReg = LegalDest;
1002 NewBaseOffset = Offset; 1002 NewBaseOffset = Offset;
1003 continue; 1003 continue;
1004 } 1004 }
1005 } 1005 }
1006 assert(MovInst->getSrcSize() == 1); 1006 assert(MovInst->getSrcSize() == 1);
1007 Variable *Var = llvm::dyn_cast<Variable>(MovInst->getSrc(0)); 1007 Variable *Var = llvm::dyn_cast<Variable>(MovInst->getSrc(0));
1008 if (Var && !Var->hasReg()) { 1008 if (Var && !Var->hasReg()) {
1009 int32_t Offset = Var->getStackOffset(); 1009 int32_t Offset = Var->getStackOffset();
1010 Offset += StackAdjust; 1010 Offset += StackAdjust;
1011 if (!isLegalVariableStackOffset(Offset)) { 1011 if (!isLegalVariableStackOffset(Offset)) {
1012 if (NewBaseReg) { 1012 if (NewBaseReg) {
1013 int32_t OffsetDiff = Offset - NewBaseOffset; 1013 int32_t OffsetDiff = Offset - NewBaseOffset;
1014 if (isLegalVariableStackOffset(OffsetDiff)) { 1014 if (isLegalVariableStackOffset(OffsetDiff)) {
1015 StackVariable *NewVar = 1015 StackVariable *NewVar =
1016 Func->makeVariable<StackVariable>(stackSlotType()); 1016 Func->makeVariable<StackVariable>(stackSlotType());
1017 NewVar->setWeight(RegWeight::Zero); 1017 NewVar->setMustNotHaveReg();
1018 NewVar->setBaseRegNum(NewBaseReg->getBaseRegNum()); 1018 NewVar->setBaseRegNum(NewBaseReg->getBaseRegNum());
1019 NewVar->setStackOffset(OffsetDiff); 1019 NewVar->setStackOffset(OffsetDiff);
1020 _mov(Dest, NewVar); 1020 _mov(Dest, NewVar);
1021 MovInst->setDeleted(); 1021 MovInst->setDeleted();
1022 continue; 1022 continue;
1023 } 1023 }
1024 } 1024 }
1025 StackVariable *LegalVar = legalizeVariableSlot(Var, OrigBaseReg); 1025 StackVariable *LegalVar = legalizeVariableSlot(Var, OrigBaseReg);
1026 assert(LegalVar != Var); 1026 assert(LegalVar != Var);
1027 _mov(Dest, LegalVar); 1027 _mov(Dest, LegalVar);
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after
2827 _movt(BaseReg, Offset); 2827 _movt(BaseReg, Offset);
2828 From = formMemoryOperand(BaseReg, Ty); 2828 From = formMemoryOperand(BaseReg, Ty);
2829 return copyToReg(From, RegNum); 2829 return copyToReg(From, RegNum);
2830 } 2830 }
2831 } 2831 }
2832 2832
2833 if (auto Var = llvm::dyn_cast<Variable>(From)) { 2833 if (auto Var = llvm::dyn_cast<Variable>(From)) {
2834 // Check if the variable is guaranteed a physical register. This 2834 // Check if the variable is guaranteed a physical register. This
2835 // can happen either when the variable is pre-colored or when it is 2835 // can happen either when the variable is pre-colored or when it is
2836 // assigned infinite weight. 2836 // assigned infinite weight.
2837 bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf()); 2837 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
2838 // We need a new physical register for the operand if: 2838 // We need a new physical register for the operand if:
2839 // Mem is not allowed and Var isn't guaranteed a physical 2839 // Mem is not allowed and Var isn't guaranteed a physical
2840 // register, or 2840 // register, or
2841 // RegNum is required and Var->getRegNum() doesn't match. 2841 // RegNum is required and Var->getRegNum() doesn't match.
2842 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 2842 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
2843 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 2843 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
2844 From = copyToReg(From, RegNum); 2844 From = copyToReg(From, RegNum);
2845 } 2845 }
2846 return From; 2846 return From;
2847 } 2847 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2892 return OperandARM32Mem::create( 2892 return OperandARM32Mem::create(
2893 Func, Ty, Base, 2893 Func, Ty, Base,
2894 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); 2894 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32)));
2895 } 2895 }
2896 2896
2897 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { 2897 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) {
2898 // There aren't any 64-bit integer registers for ARM32. 2898 // There aren't any 64-bit integer registers for ARM32.
2899 assert(Type != IceType_i64); 2899 assert(Type != IceType_i64);
2900 Variable *Reg = Func->makeVariable(Type); 2900 Variable *Reg = Func->makeVariable(Type);
2901 if (RegNum == Variable::NoRegister) 2901 if (RegNum == Variable::NoRegister)
2902 Reg->setWeightInfinite(); 2902 Reg->setMustHaveReg();
2903 else 2903 else
2904 Reg->setRegNum(RegNum); 2904 Reg->setRegNum(RegNum);
2905 return Reg; 2905 return Reg;
2906 } 2906 }
2907 2907
2908 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align) { 2908 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align) {
2909 assert(llvm::isPowerOf2_32(Align)); 2909 assert(llvm::isPowerOf2_32(Align));
2910 uint32_t RotateAmt; 2910 uint32_t RotateAmt;
2911 uint32_t Immed_8; 2911 uint32_t Immed_8;
2912 Operand *Mask; 2912 Operand *Mask;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 3039 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
3040 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 3040 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
3041 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 3041 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
3042 } 3042 }
3043 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 3043 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
3044 // However, for compatibility with current NaCl LLVM, don't claim that. 3044 // However, for compatibility with current NaCl LLVM, don't claim that.
3045 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 3045 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
3046 } 3046 }
3047 3047
3048 } // end of namespace Ice 3048 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698