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

Side by Side Diff: src/IceTargetLoweringARM32.h

Issue 1477873002: Subzero. ARM32. Folding rematerializable offsets in address operands. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make format Created 5 years 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/IceInstARM32.cpp ('k') | src/IceTargetLoweringARM32.cpp » ('j') | 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/IceTargetLoweringARM32.h - ARM32 lowering ----*- C++ -*-===// 1 //===- subzero/src/IceTargetLoweringARM32.h - ARM32 lowering ----*- C++ -*-===//
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 const llvm::SmallBitVector &getAliasesForRegister(SizeT Reg) const override { 83 const llvm::SmallBitVector &getAliasesForRegister(SizeT Reg) const override {
84 return RegisterAliases[Reg]; 84 return RegisterAliases[Reg];
85 } 85 }
86 bool hasFramePointer() const override { return UsesFramePointer; } 86 bool hasFramePointer() const override { return UsesFramePointer; }
87 void setHasFramePointer() override { UsesFramePointer = true; } 87 void setHasFramePointer() override { UsesFramePointer = true; }
88 SizeT getStackReg() const override { return RegARM32::Reg_sp; } 88 SizeT getStackReg() const override { return RegARM32::Reg_sp; }
89 SizeT getFrameReg() const override { return RegARM32::Reg_fp; } 89 SizeT getFrameReg() const override { return RegARM32::Reg_fp; }
90 SizeT getFrameOrStackReg() const override { 90 SizeT getFrameOrStackReg() const override {
91 return UsesFramePointer ? getFrameReg() : getStackReg(); 91 return UsesFramePointer ? getFrameReg() : getStackReg();
92 } 92 }
93 SizeT getReservedTmpReg() const { return RegARM32::Reg_ip; } 93 int32_t getReservedTmpReg() const { return RegARM32::Reg_ip; }
94 94
95 size_t typeWidthInBytesOnStack(Type Ty) const override { 95 size_t typeWidthInBytesOnStack(Type Ty) const override {
96 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16 96 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16
97 // are rounded up to 4 bytes. 97 // are rounded up to 4 bytes.
98 return (typeWidthInBytes(Ty) + 3) & ~3; 98 return (typeWidthInBytes(Ty) + 3) & ~3;
99 } 99 }
100 uint32_t getStackAlignment() const override; 100 uint32_t getStackAlignment() const override;
101 void reserveFixedAllocaArea(size_t Size, size_t Align) override { 101 void reserveFixedAllocaArea(size_t Size, size_t Align) override {
102 FixedAllocaSizeBytes = Size; 102 FixedAllocaSizeBytes = Size;
103 assert(llvm::isPowerOf2_32(Align)); 103 assert(llvm::isPowerOf2_32(Align));
(...skipping 30 matching lines...) Expand all
134 Operand *loOperand(Operand *Operand); 134 Operand *loOperand(Operand *Operand);
135 Operand *hiOperand(Operand *Operand); 135 Operand *hiOperand(Operand *Operand);
136 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, 136 void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
137 size_t BasicFrameOffset, size_t *InArgsSizeBytes); 137 size_t BasicFrameOffset, size_t *InArgsSizeBytes);
138 138
139 bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const { 139 bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const {
140 return CPUFeatures.hasFeature(I); 140 return CPUFeatures.hasFeature(I);
141 } 141 }
142 142
143 enum OperandLegalization { 143 enum OperandLegalization {
144 Legal_None = 0,
145 Legal_Reg = 1 << 0, /// physical register, not stack location 144 Legal_Reg = 1 << 0, /// physical register, not stack location
146 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small 145 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small
147 /// immediates, shifted registers, or modified fp imm. 146 /// immediates, shifted registers, or modified fp imm.
148 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] 147 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12]
149 Legal_All = ~Legal_None 148 Legal_Rematerializable = 1 << 3,
149 Legal_All = ~Legal_Rematerializable,
150 }; 150 };
151 151
152 using LegalMask = uint32_t; 152 using LegalMask = uint32_t;
153 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); 153 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister);
154 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, 154 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
155 int32_t RegNum = Variable::NoRegister); 155 int32_t RegNum = Variable::NoRegister);
156 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); 156 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister);
157 157
158 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const { 158 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const {
159 assert(ShAmtImm < 32); 159 assert(ShAmtImm < 32);
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 Context.insert(InstARM32Vsub::create(Func, Dest, Src0, Src1)); 809 Context.insert(InstARM32Vsub::create(Func, Dest, Src0, Src1));
810 } 810 }
811 811
812 // Iterates over the CFG and determines the maximum outgoing stack arguments 812 // Iterates over the CFG and determines the maximum outgoing stack arguments
813 // bytes. This information is later used during addProlog() to pre-allocate 813 // bytes. This information is later used during addProlog() to pre-allocate
814 // the outargs area. 814 // the outargs area.
815 // TODO(jpp): This could live in the Parser, if we provided a Target-specific 815 // TODO(jpp): This could live in the Parser, if we provided a Target-specific
816 // method that the Parser could call. 816 // method that the Parser could call.
817 void findMaxStackOutArgsSize(); 817 void findMaxStackOutArgsSize();
818 818
819 /// Run a pass through stack variables and ensure that the offsets are legal. 819 /// Returns true if the given Offset can be represented in a Load/Store Mem
820 /// If the offset is not legal, use a new base register that accounts for the 820 /// Operand.
821 /// offset, such that the addressing mode offset bits are now legal.
822 void legalizeStackSlots();
823 /// Returns true if the given Offset can be represented in a ldr/str.
824 bool isLegalMemOffset(Type Ty, int32_t Offset) const; 821 bool isLegalMemOffset(Type Ty, int32_t Offset) const;
825 // Creates a new Base register centered around 822
826 // [OrigBaseReg, +/- Offset]. 823 void postLowerLegalization();
827 Variable *newBaseRegister(int32_t Offset, Variable *OrigBaseReg); 824
828 /// Creates a new, legal OperandARM32Mem for accessing OrigBase + Offset. The 825 class PostLoweringLegalizer {
829 /// returned mem operand is a legal operand for accessing memory that is of 826 PostLoweringLegalizer() = delete;
830 /// type Ty. 827 PostLoweringLegalizer(const PostLoweringLegalizer &) = delete;
831 /// 828 PostLoweringLegalizer &operator=(const PostLoweringLegalizer &) = delete;
832 /// If [OrigBaseReg, #Offset] is encodable, then the method returns a Mem 829
833 /// operand expressing it. Otherwise, 830 public:
834 /// 831 explicit PostLoweringLegalizer(TargetARM32 *Target)
835 /// if [*NewBaseReg, #Offset-*NewBaseOffset] is encodable, the method will 832 : Target(Target), StackOrFrameReg(Target->getPhysicalRegister(
836 /// return that. Otherwise, 833 Target->getFrameOrStackReg())) {}
837 /// 834
838 /// a new base register ip=OrigBaseReg+Offset is created, and the method 835 void resetTempBaseIfClobberedBy(const Inst *Instr);
839 /// returns [ip, #0]. 836
840 OperandARM32Mem *createMemOperand(Type Ty, int32_t Offset, 837 // Ensures that the TempBase register held by the this legalizer (if any) is
841 Variable *OrigBaseReg, 838 // assigned to IP.
842 Variable **NewBaseReg, 839 void assertNoTempOrAssignedToIP() const {
843 int32_t *NewBaseOffset); 840 assert(TempBaseReg == nullptr ||
844 /// Legalizes Mov if its Source (or Destination) is a spilled Variable. Moves 841 TempBaseReg->getRegNum() == Target->getReservedTmpReg());
845 /// to memory become store instructions, and moves from memory, loads. 842 }
846 void legalizeMov(InstARM32Mov *Mov, Variable *OrigBaseReg, 843
847 Variable **NewBaseReg, int32_t *NewBaseOffset); 844 // Legalizes Mem. if Mem.Base is a Reamaterializable variable, Mem.Offset is
845 // fixed up.
846 OperandARM32Mem *legalizeMemOperand(OperandARM32Mem *Mem,
847 bool AllowOffsets = true);
848
849 /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or
850 /// if its Source is a Rematerializable variable (this form is used in lieu
851 /// of lea, which is not available in ARM.)
852 ///
853 /// Moves to memory become store instructions, and moves from memory, loads.
854 void legalizeMov(InstARM32Mov *Mov);
855
856 private:
857 /// Creates a new Base register centered around [Base, +/- Offset].
858 Variable *newBaseRegister(Variable *Base, int32_t Offset,
859 int32_t ScratchRegNum);
860
861 /// Creates a new, legal OperandARM32Mem for accessing Base + Offset.
862 /// The returned mem operand is a legal operand for accessing memory that is
863 /// of type Ty.
864 ///
865 /// If [Base, #Offset] is encodable, then the method returns a Mem operand
866 /// expressing it. Otherwise,
867 ///
868 /// if [TempBaseReg, #Offset-TempBaseOffset] is a valid memory operand, the
869 /// method will return that. Otherwise,
870 ///
871 /// a new base register ip=Base+Offset is created, and the method returns a
872 /// memory operand expressing [ip, #0].
873 OperandARM32Mem *createMemOperand(Type Ty, Variable *Base, int32_t Offset,
874 bool AllowOffsets = true);
875 TargetARM32 *const Target;
876 Variable *const StackOrFrameReg;
877 Variable *TempBaseReg = nullptr;
878 int32_t TempBaseOffset = 0;
879 };
848 880
849 TargetARM32Features CPUFeatures; 881 TargetARM32Features CPUFeatures;
850 bool UsesFramePointer = false; 882 bool UsesFramePointer = false;
851 bool NeedsStackAlignment = false; 883 bool NeedsStackAlignment = false;
852 bool MaybeLeafFunc = true; 884 bool MaybeLeafFunc = true;
853 size_t SpillAreaSizeBytes = 0; 885 size_t SpillAreaSizeBytes = 0;
854 size_t FixedAllocaSizeBytes = 0; 886 size_t FixedAllocaSizeBytes = 0;
855 size_t FixedAllocaAlignBytes = 0; 887 size_t FixedAllocaAlignBytes = 0;
856 bool PrologEmitsFixedAllocas = false; 888 bool PrologEmitsFixedAllocas = false;
857 uint32_t MaxOutArgsSizeBytes = 0; 889 uint32_t MaxOutArgsSizeBytes = 0;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 1076
1045 private: 1077 private:
1046 ~TargetHeaderARM32() = default; 1078 ~TargetHeaderARM32() = default;
1047 1079
1048 TargetARM32Features CPUFeatures; 1080 TargetARM32Features CPUFeatures;
1049 }; 1081 };
1050 1082
1051 } // end of namespace Ice 1083 } // end of namespace Ice
1052 1084
1053 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H 1085 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H
OLDNEW
« no previous file with comments | « src/IceInstARM32.cpp ('k') | src/IceTargetLoweringARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698