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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2417233002: [Subzero][MIPS32] Fix alloca alignment and offset for Om1 and O2 optimization (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Changed comment in legalizeMov() Created 4 years, 2 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/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/alloc.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // 1 //
2 // The Subzero Code Generator 2 // The Subzero Code Generator
3 // 3 //
4 // This file is distributed under the University of Illinois Open Source 4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details. 5 // License. See LICENSE.TXT for details.
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 /// 8 ///
9 /// \file 9 /// \file
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 return; 209 return;
210 } 210 }
211 } 211 }
212 } 212 }
213 } 213 }
214 214
215 uint32_t TargetMIPS32::getStackAlignment() const { 215 uint32_t TargetMIPS32::getStackAlignment() const {
216 return MIPS32_STACK_ALIGNMENT_BYTES; 216 return MIPS32_STACK_ALIGNMENT_BYTES;
217 } 217 }
218 218
219 uint32_t TargetMIPS32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
220 TargetMIPS32::CallingConv CC;
221 RegNumT DummyReg;
222 size_t OutArgsSizeBytes = 0;
223 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
224 Operand *Arg = legalizeUndef(Call->getArg(i));
225 const Type Ty = Arg->getType();
226 RegNumT RegNum;
227 if (CC.argInReg(Ty, i, &RegNum)) {
228 continue;
229 }
230
231 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty);
232 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty);
233 }
234
235 return applyStackAlignment(OutArgsSizeBytes);
236 }
237
219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { 238 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) {
220 constexpr bool NoTailCall = false; 239 constexpr bool NoTailCall = false;
221 constexpr bool IsTargetHelperCall = true; 240 constexpr bool IsTargetHelperCall = true;
222 241
223 switch (Instr->getKind()) { 242 switch (Instr->getKind()) {
224 default: 243 default:
225 return; 244 return;
226 case Inst::Arithmetic: { 245 case Inst::Arithmetic: {
227 Variable *Dest = Instr->getDest(); 246 Variable *Dest = Instr->getDest();
228 const Type DestTy = Dest->getType(); 247 const Type DestTy = Dest->getType();
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 Context.init(Node); 598 Context.init(Node);
580 while (!Context.atEnd()) { 599 while (!Context.atEnd()) {
581 PostIncrLoweringContext PostIncrement(Context); 600 PostIncrLoweringContext PostIncrement(Context);
582 Inst *CurInstr = iteratorToInst(Context.getCur()); 601 Inst *CurInstr = iteratorToInst(Context.getCur());
583 if (auto *Call = llvm::dyn_cast<InstCall>(CurInstr)) { 602 if (auto *Call = llvm::dyn_cast<InstCall>(CurInstr)) {
584 SizeT OutArgsSizeBytes = getCallStackArgumentsSizeBytes(Call); 603 SizeT OutArgsSizeBytes = getCallStackArgumentsSizeBytes(Call);
585 MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, OutArgsSizeBytes); 604 MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, OutArgsSizeBytes);
586 } 605 }
587 } 606 }
588 } 607 }
608 CurrentAllocaOffset = MaxOutArgsSizeBytes;
589 } 609 }
590 610
591 void TargetMIPS32::translateO2() { 611 void TargetMIPS32::translateO2() {
592 TimerMarker T(TimerStack::TT_O2, Func); 612 TimerMarker T(TimerStack::TT_O2, Func);
593 613
594 // TODO(stichnot): share passes with X86? 614 // TODO(stichnot): share passes with X86?
595 // https://code.google.com/p/nativeclient/issues/detail?id=4094 615 // https://code.google.com/p/nativeclient/issues/detail?id=4094
596 genTargetHelperCalls(); 616 genTargetHelperCalls();
597 617
598 unsetIfNonLeafFunc(); 618 unsetIfNonLeafFunc();
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 } else { 1709 } else {
1690 Target->_sw(SrcR, Addr); 1710 Target->_sw(SrcR, Addr);
1691 } 1711 }
1692 1712
1693 Target->Context.insert<InstFakeDef>(Dest); 1713 Target->Context.insert<InstFakeDef>(Dest);
1694 Legalized = true; 1714 Legalized = true;
1695 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1715 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1696 if (Var->isRematerializable()) { 1716 if (Var->isRematerializable()) {
1697 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1717 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1698 1718
1699 // ExtraOffset is only needed for frame-pointer based frames as we have 1719 // ExtraOffset is only needed for stack-pointer based frames as we have
1700 // to account for spill storage. 1720 // to account for spill storage.
1701 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) 1721 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg())
1702 ? Target->getFrameFixedAllocaOffset() 1722 ? Target->getFrameFixedAllocaOffset()
1703 : 0; 1723 : 0;
1704 1724
1705 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1725 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1706 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1726 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1707 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1727 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1708 Target->_mov(Dest, T); 1728 Target->_mov(Dest, T);
1709 Legalized = true; 1729 Legalized = true;
1710 } else { 1730 } else {
1711 if (!Var->hasReg()) { 1731 if (!Var->hasReg()) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 FixedAllocaSizeBytes += Value; 1935 FixedAllocaSizeBytes += Value;
1916 // Constant size alloca. 1936 // Constant size alloca.
1917 if (!UseFramePointer) { 1937 if (!UseFramePointer) {
1918 // If we don't need a Frame Pointer, this alloca has a known offset to the 1938 // If we don't need a Frame Pointer, this alloca has a known offset to the
1919 // stack pointer. We don't need adjust the stack pointer, nor assign any 1939 // stack pointer. We don't need adjust the stack pointer, nor assign any
1920 // value to Dest, as Dest is rematerializable. 1940 // value to Dest, as Dest is rematerializable.
1921 assert(Dest->isRematerializable()); 1941 assert(Dest->isRematerializable());
1922 Context.insert<InstFakeDef>(Dest); 1942 Context.insert<InstFakeDef>(Dest);
1923 return; 1943 return;
1924 } 1944 }
1945
1946 if (Alignment > MIPS32_STACK_ALIGNMENT_BYTES) {
1947 CurrentAllocaOffset =
1948 Utils::applyAlignment(CurrentAllocaOffset, Alignment);
1949 }
1950 auto *T = I32Reg();
1951 _addiu(T, SP, CurrentAllocaOffset);
1952 _mov(Dest, T);
1953 CurrentAllocaOffset += Value;
1954 return;
1955
1925 } else { 1956 } else {
1926 // Non-constant sizes need to be adjusted to the next highest multiple of 1957 // Non-constant sizes need to be adjusted to the next highest multiple of
1927 // the required alignment at runtime. 1958 // the required alignment at runtime.
1928 VariableAllocaUsed = true; 1959 VariableAllocaUsed = true;
1929 Variable *AlignAmount; 1960 Variable *AlignAmount;
1930 auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg); 1961 auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg);
1931 auto *T1 = I32Reg(); 1962 auto *T1 = I32Reg();
1932 auto *T2 = I32Reg(); 1963 auto *T2 = I32Reg();
1933 auto *T3 = I32Reg(); 1964 auto *T3 = I32Reg();
1934 auto *T4 = I32Reg(); 1965 auto *T4 = I32Reg();
1935 auto *T5 = I32Reg(); 1966 auto *T5 = I32Reg();
1936 _addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1); 1967 _addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1);
1937 _addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES); 1968 _addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES);
1938 _and(T3, T1, T2); 1969 _and(T3, T1, T2);
1939 _subu(T4, SP, T3); 1970 _subu(T4, SP, T3);
1940 if (Instr->getAlignInBytes()) { 1971 if (Instr->getAlignInBytes()) {
1941 AlignAmount = 1972 AlignAmount =
1942 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg); 1973 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg);
1943 _and(T5, T4, AlignAmount); 1974 _and(T5, T4, AlignAmount);
1944 _mov(Dest, T5); 1975 _mov(Dest, T5);
1945 } else { 1976 } else {
1946 _mov(Dest, T4); 1977 _mov(Dest, T4);
1947 } 1978 }
1948 _mov(SP, Dest); 1979 _mov(SP, Dest);
1949 return; 1980 return;
1950 } 1981 }
1951
1952 // Add enough to the returned address to account for the out args area.
1953 if (MaxOutArgsSizeBytes > 0) {
1954 Variable *T = makeReg(getPointerType());
1955 _addiu(T, SP, MaxOutArgsSizeBytes);
1956 _mov(Dest, T);
1957 } else {
1958 _mov(Dest, SP);
1959 }
1960 } 1982 }
1961 1983
1962 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, 1984 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
1963 Variable *Dest, Operand *Src0, 1985 Variable *Dest, Operand *Src0,
1964 Operand *Src1) { 1986 Operand *Src1) {
1965 InstArithmetic::OpKind Op = Instr->getOp(); 1987 InstArithmetic::OpKind Op = Instr->getOp();
1966 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1988 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
1967 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1989 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1968 Variable *Src0LoR = nullptr; 1990 Variable *Src0LoR = nullptr;
1969 Variable *Src1LoR = nullptr; 1991 Variable *Src1LoR = nullptr;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2229 return; 2251 return;
2230 } 2252 }
2231 default: 2253 default:
2232 UnimplementedLoweringError(this, Instr); 2254 UnimplementedLoweringError(this, Instr);
2233 return; 2255 return;
2234 } 2256 }
2235 } 2257 }
2236 2258
2237 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { 2259 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
2238 Variable *Dest = Instr->getDest(); 2260 Variable *Dest = Instr->getDest();
2261
2262 if (Dest->isRematerializable()) {
2263 Context.insert<InstFakeDef>(Dest);
2264 return;
2265 }
2266
2239 // We need to signal all the UnimplementedLoweringError errors before any 2267 // We need to signal all the UnimplementedLoweringError errors before any
2240 // legalization into new variables, otherwise Om1 register allocation may fail 2268 // legalization into new variables, otherwise Om1 register allocation may fail
2241 // when it sees variables that are defined but not used. 2269 // when it sees variables that are defined but not used.
2242 Type DestTy = Dest->getType(); 2270 Type DestTy = Dest->getType();
2243 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); 2271 Operand *Src0 = legalizeUndef(Instr->getSrc(0));
2244 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); 2272 Operand *Src1 = legalizeUndef(Instr->getSrc(1));
2245 if (DestTy == IceType_i64) { 2273 if (DestTy == IceType_i64) {
2246 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); 2274 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1);
2247 return; 2275 return;
2248 } 2276 }
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after
5000 Str << "\t.set\t" 5028 Str << "\t.set\t"
5001 << "nomips16\n"; 5029 << "nomips16\n";
5002 } 5030 }
5003 5031
5004 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 5032 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
5005 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 5033 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
5006 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 5034 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
5007 5035
5008 } // end of namespace MIPS32 5036 } // end of namespace MIPS32
5009 } // end of namespace Ice 5037 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/alloc.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698