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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2063653003: LowerCall for MIPS32 (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Removing conflict Created 4 years, 6 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 | « no previous file | tests_lit/llvm2ice_tests/callArgs.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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 auto ClassNum = static_cast<RegClassMIPS32>(C); 76 auto ClassNum = static_cast<RegClassMIPS32>(C);
77 assert(ClassNum < RCMIPS32_NUM); 77 assert(ClassNum < RCMIPS32_NUM);
78 switch (ClassNum) { 78 switch (ClassNum) {
79 default: 79 default:
80 assert(C < RC_Target); 80 assert(C < RC_Target);
81 return regClassString(C); 81 return regClassString(C);
82 // Add handling of new register classes below. 82 // Add handling of new register classes below.
83 } 83 }
84 } 84 }
85 85
86 // Value is in bytes. Return Value adjusted to the next highest multiple of the
87 // stack alignment.
88 uint32_t applyStackAlignment(uint32_t Value) {
89 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES);
90 }
91
86 } // end of anonymous namespace 92 } // end of anonymous namespace
87 93
88 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} 94 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {}
89 95
90 void TargetMIPS32::staticInit(GlobalContext *Ctx) { 96 void TargetMIPS32::staticInit(GlobalContext *Ctx) {
91 (void)Ctx; 97 (void)Ctx;
92 RegNumT::setLimit(RegMIPS32::Reg_NUM); 98 RegNumT::setLimit(RegMIPS32::Reg_NUM);
93 SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); 99 SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM);
94 SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); 100 SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM);
95 SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); 101 SmallBitVector Float32Registers(RegMIPS32::Reg_NUM);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // Register allocation. This requires instruction renumbering and full 215 // Register allocation. This requires instruction renumbering and full
210 // liveness analysis. 216 // liveness analysis.
211 Func->renumberInstructions(); 217 Func->renumberInstructions();
212 if (Func->hasError()) 218 if (Func->hasError())
213 return; 219 return;
214 Func->liveness(Liveness_Intervals); 220 Func->liveness(Liveness_Intervals);
215 if (Func->hasError()) 221 if (Func->hasError())
216 return; 222 return;
217 // Validate the live range computations. The expensive validation call is 223 // Validate the live range computations. The expensive validation call is
218 // deliberately only made when assertions are enabled. 224 // deliberately only made when assertions are enabled.
219 assert(Func->validateLiveness()); 225 assert(Func->validateLiveness());
Jim Stichnoth 2016/06/21 13:44:00 I recommend moving this assert (and its two commen
Jim Stichnoth 2016/06/21 13:46:17 BTW, I forgot to mention that this same change oug
220 // The post-codegen dump is done here, after liveness analysis and associated 226 // The post-codegen dump is done here, after liveness analysis and associated
221 // cleanup, to make the dump cleaner and more useful. 227 // cleanup, to make the dump cleaner and more useful.
222 Func->dump("After initial MIPS32 codegen"); 228 Func->dump("After initial MIPS32 codegen");
223 Func->getVMetadata()->init(VMK_All); 229 Func->getVMetadata()->init(VMK_All);
224 regAlloc(RAK_Global); 230 regAlloc(RAK_Global);
225 if (Func->hasError()) 231 if (Func->hasError())
226 return; 232 return;
227 Func->dump("After linear scan regalloc"); 233 Func->dump("After linear scan regalloc");
228 234
229 if (getFlags().getEnablePhiEdgeSplit()) { 235 if (getFlags().getEnablePhiEdgeSplit()) {
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 case InstIcmp::Sle: { 1083 case InstIcmp::Sle: {
1078 _slt(DestT, Src1R, Src0R); 1084 _slt(DestT, Src1R, Src0R);
1079 _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); 1085 _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ);
1080 break; 1086 break;
1081 } 1087 }
1082 } 1088 }
1083 } 1089 }
1084 } 1090 }
1085 1091
1086 void TargetMIPS32::lowerCall(const InstCall *Instr) { 1092 void TargetMIPS32::lowerCall(const InstCall *Instr) {
1087 // TODO(rkotler): assign arguments to registers and stack. Also reserve stack. 1093 NeedsStackAlignment = true;
1088 if (Instr->getNumArgs()) { 1094
1089 UnimplementedLoweringError(this, Instr); 1095 // Assign arguments to registers and stack. Also reserve stack.
1090 return; 1096 TargetMIPS32::CallingConv CC;
1097
1098 // Pair of Arg Operand -> GPR number assignments.
1099 llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_GPR_ARG> GPRArgs;
1100 llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_FP_ARG> FPArgs;
1101 // Pair of Arg Operand -> stack offset.
1102 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
1103 size_t ParameterAreaSizeBytes = 16;
1104
1105 // Classify each argument operand according to the location where the
1106 // argument is passed.
1107
1108 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
1109 Operand *Arg = legalizeUndef(Instr->getArg(i));
1110 const Type Ty = Arg->getType();
1111 bool InReg = false;
1112 RegNumT Reg;
1113
1114 InReg = CC.argInReg(Ty, i, &Reg);
1115
1116 if (!InReg) {
1117 ParameterAreaSizeBytes =
1118 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
1119 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
1120 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
1121 continue;
1122 }
1123
1124 if (Ty == IceType_i64) {
1125 Operand *Lo = loOperand(Arg);
1126 Operand *Hi = hiOperand(Arg);
1127 GPRArgs.push_back(
1128 std::make_pair(Lo, RegMIPS32::getI64PairFirstGPRNum(Reg)));
1129 GPRArgs.push_back(
1130 std::make_pair(Hi, RegMIPS32::getI64PairSecondGPRNum(Reg)));
1131 } else if (isScalarIntegerType(Ty)) {
1132 GPRArgs.push_back(std::make_pair(Arg, Reg));
1133 } else {
1134 FPArgs.push_back(std::make_pair(Arg, Reg));
1135 }
1091 } 1136 }
1137
1138 // Adjust the parameter area so that the stack is aligned. It is assumed that
1139 // the stack is already aligned at the start of the calling sequence.
1140 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
1141
1142 // Copy arguments that are passed on the stack to the appropriate stack
1143 // locations.
1144 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
1145 for (auto &StackArg : StackArgs) {
1146 ConstantInteger32 *Loc =
1147 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackArg.second));
1148 Type Ty = StackArg.first->getType();
1149 OperandMIPS32Mem *Addr;
1150 constexpr bool SignExt = false;
1151 if (OperandMIPS32Mem::canHoldOffset(Ty, SignExt, StackArg.second)) {
1152 Addr = OperandMIPS32Mem::create(Func, Ty, SP, Loc);
1153 } else {
1154 Variable *NewBase = Func->makeVariable(SP->getType());
1155 lowerArithmetic(
1156 InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc));
1157 Addr = formMemoryOperand(NewBase, Ty);
1158 }
1159 lowerStore(InstStore::create(Func, StackArg.first, Addr));
1160 }
1161
1092 // Generate the call instruction. Assign its result to a temporary with high 1162 // Generate the call instruction. Assign its result to a temporary with high
1093 // register allocation weight. 1163 // register allocation weight.
1094 Variable *Dest = Instr->getDest(); 1164 Variable *Dest = Instr->getDest();
1095 // ReturnReg doubles as ReturnRegLo as necessary. 1165 // ReturnReg doubles as ReturnRegLo as necessary.
1096 Variable *ReturnReg = nullptr; 1166 Variable *ReturnReg = nullptr;
1097 Variable *ReturnRegHi = nullptr; 1167 Variable *ReturnRegHi = nullptr;
1098 if (Dest) { 1168 if (Dest) {
1099 switch (Dest->getType()) { 1169 switch (Dest->getType()) {
1100 case IceType_NUM: 1170 case IceType_NUM:
1101 llvm_unreachable("Invalid Call dest type"); 1171 llvm_unreachable("Invalid Call dest type");
(...skipping 25 matching lines...) Expand all
1127 return; 1197 return;
1128 } 1198 }
1129 } 1199 }
1130 Operand *CallTarget = Instr->getCallTarget(); 1200 Operand *CallTarget = Instr->getCallTarget();
1131 // Allow ConstantRelocatable to be left alone as a direct call, 1201 // Allow ConstantRelocatable to be left alone as a direct call,
1132 // but force other constants like ConstantInteger32 to be in 1202 // but force other constants like ConstantInteger32 to be in
1133 // a register and make it an indirect call. 1203 // a register and make it an indirect call.
1134 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { 1204 if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
1135 CallTarget = legalize(CallTarget, Legal_Reg); 1205 CallTarget = legalize(CallTarget, Legal_Reg);
1136 } 1206 }
1207
1208 // Copy arguments to be passed in registers to the appropriate registers.
1209 CfgVector<Variable *> RegArgs;
1210 for (auto &FPArg : FPArgs) {
1211 RegArgs.emplace_back(legalizeToReg(FPArg.first, FPArg.second));
1212 }
1213 for (auto &GPRArg : GPRArgs) {
1214 RegArgs.emplace_back(legalizeToReg(GPRArg.first, GPRArg.second));
1215 }
1216
1217 // Generate a FakeUse of register arguments so that they do not get dead code
1218 // eliminated as a result of the FakeKill of scratch registers after the call.
1219 // These fake-uses need to be placed here to avoid argument registers from
1220 // being used during the legalizeToReg() calls above.
1221 for (auto *RegArg : RegArgs) {
1222 Context.insert<InstFakeUse>(RegArg);
1223 }
1224
1137 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); 1225 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget);
1138 Context.insert(NewCall); 1226 Context.insert(NewCall);
1139 if (ReturnRegHi) 1227 if (ReturnRegHi)
1140 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); 1228 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
1141 // Insert a register-kill pseudo instruction. 1229 // Insert a register-kill pseudo instruction.
1142 Context.insert(InstFakeKill::create(Func, NewCall)); 1230 Context.insert(InstFakeKill::create(Func, NewCall));
1143 // Generate a FakeUse to keep the call live if necessary. 1231 // Generate a FakeUse to keep the call live if necessary.
1144 if (Instr->hasSideEffects() && ReturnReg) { 1232 if (Instr->hasSideEffects() && ReturnReg) {
1145 Context.insert<InstFakeDef>(ReturnReg); 1233 Context.insert<InstFakeDef>(ReturnReg);
Jim Stichnoth 2016/06/21 13:44:00 InstFakeUse
1146 } 1234 }
1147 if (Dest == nullptr) 1235 if (Dest == nullptr)
1148 return; 1236 return;
1149 1237
1150 // Assign the result of the call to Dest. 1238 // Assign the result of the call to Dest.
1151 if (ReturnReg) { 1239 if (ReturnReg) {
1152 if (ReturnRegHi) { 1240 if (ReturnRegHi) {
1153 assert(Dest->getType() == IceType_i64); 1241 assert(Dest->getType() == IceType_i64);
1154 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); 1242 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
1155 Variable *DestLo = Dest64On32->getLo(); 1243 Variable *DestLo = Dest64On32->getLo();
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 Str << "\t.set\t" 1956 Str << "\t.set\t"
1869 << "nomips16\n"; 1957 << "nomips16\n";
1870 } 1958 }
1871 1959
1872 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1960 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1873 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1961 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1874 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1962 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1875 1963
1876 } // end of namespace MIPS32 1964 } // end of namespace MIPS32
1877 } // end of namespace Ice 1965 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/callArgs.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698