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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1676123002: Subzero: Use a proper RegNumT type instead of int32_t/SizeT. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make it possible to do "auto NewReg = RegNumT::NoRegister;" Created 4 years, 10 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/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringMIPS32.h » ('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.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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 226 }
227 227
228 namespace { 228 namespace {
229 constexpr SizeT NumGPRArgs = 229 constexpr SizeT NumGPRArgs =
230 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 230 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
231 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 231 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
232 +(((cc_arg) > 0) ? 1 : 0) 232 +(((cc_arg) > 0) ? 1 : 0)
233 REGARM32_GPR_TABLE 233 REGARM32_GPR_TABLE
234 #undef X 234 #undef X
235 ; 235 ;
236 std::array<uint32_t, NumGPRArgs> GPRArgInitializer; 236 std::array<RegNumT, NumGPRArgs> GPRArgInitializer;
237 237
238 constexpr SizeT NumI64Args = 238 constexpr SizeT NumI64Args =
239 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 239 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
240 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 240 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
241 +(((cc_arg) > 0) ? 1 : 0) 241 +(((cc_arg) > 0) ? 1 : 0)
242 REGARM32_I64PAIR_TABLE 242 REGARM32_I64PAIR_TABLE
243 #undef X 243 #undef X
244 ; 244 ;
245 std::array<uint32_t, NumI64Args> I64ArgInitializer; 245 std::array<RegNumT, NumI64Args> I64ArgInitializer;
246 246
247 constexpr SizeT NumFP32Args = 247 constexpr SizeT NumFP32Args =
248 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 248 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
249 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 249 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
250 +(((cc_arg) > 0) ? 1 : 0) 250 +(((cc_arg) > 0) ? 1 : 0)
251 REGARM32_FP32_TABLE 251 REGARM32_FP32_TABLE
252 #undef X 252 #undef X
253 ; 253 ;
254 std::array<uint32_t, NumFP32Args> FP32ArgInitializer; 254 std::array<RegNumT, NumFP32Args> FP32ArgInitializer;
255 255
256 constexpr SizeT NumFP64Args = 256 constexpr SizeT NumFP64Args =
257 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 257 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
258 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 258 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
259 +(((cc_arg) > 0) ? 1 : 0) 259 +(((cc_arg) > 0) ? 1 : 0)
260 REGARM32_FP64_TABLE 260 REGARM32_FP64_TABLE
261 #undef X 261 #undef X
262 ; 262 ;
263 std::array<uint32_t, NumFP64Args> FP64ArgInitializer; 263 std::array<RegNumT, NumFP64Args> FP64ArgInitializer;
264 264
265 constexpr SizeT NumVec128Args = 265 constexpr SizeT NumVec128Args =
266 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 266 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
267 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 267 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
268 +(((cc_arg > 0)) ? 1 : 0) 268 +(((cc_arg > 0)) ? 1 : 0)
269 REGARM32_VEC128_TABLE 269 REGARM32_VEC128_TABLE
270 #undef X 270 #undef X
271 ; 271 ;
272 std::array<uint32_t, NumVec128Args> Vec128ArgInitializer; 272 std::array<RegNumT, NumVec128Args> Vec128ArgInitializer;
273 273
274 IceString getRegClassName(RegClass C) { 274 IceString getRegClassName(RegClass C) {
275 auto ClassNum = static_cast<RegARM32::RegClassARM32>(C); 275 auto ClassNum = static_cast<RegARM32::RegClassARM32>(C);
276 assert(ClassNum < RegARM32::RCARM32_NUM); 276 assert(ClassNum < RegARM32::RCARM32_NUM);
277 switch (ClassNum) { 277 switch (ClassNum) {
278 default: 278 default:
279 assert(C < RC_Target); 279 assert(C < RC_Target);
280 return regClassString(C); 280 return regClassString(C);
281 // Add handling of new register classes below. 281 // Add handling of new register classes below.
282 } 282 }
283 } 283 }
284 284
285 } // end of anonymous namespace 285 } // end of anonymous namespace
286 286
287 TargetARM32::TargetARM32(Cfg *Func) 287 TargetARM32::TargetARM32(Cfg *Func)
288 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), 288 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl),
289 CPUFeatures(Func->getContext()->getFlags()) {} 289 CPUFeatures(Func->getContext()->getFlags()) {}
290 290
291 void TargetARM32::staticInit(GlobalContext *Ctx) { 291 void TargetARM32::staticInit(GlobalContext *Ctx) {
292 292 RegNumT::setLimit(RegARM32::Reg_NUM);
293 // Limit this size (or do all bitsets need to be the same width)??? 293 // Limit this size (or do all bitsets need to be the same width)???
294 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); 294 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM);
295 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); 295 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM);
296 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); 296 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM);
297 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); 297 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM);
298 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); 298 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM);
299 llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); 299 llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM);
300 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); 300 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM);
301 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding; 301 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding;
302 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { 302 for (int i = 0; i < RegARM32::Reg_NUM; ++i) {
303 const auto &Entry = RegARM32::RegTable[i]; 303 const auto &Entry = RegARM32::RegTable[i];
304 IntegerRegisters[i] = Entry.IsInt; 304 IntegerRegisters[i] = Entry.IsInt;
305 I64PairRegisters[i] = Entry.IsI64Pair; 305 I64PairRegisters[i] = Entry.IsI64Pair;
306 Float32Registers[i] = Entry.IsFP32; 306 Float32Registers[i] = Entry.IsFP32;
307 Float64Registers[i] = Entry.IsFP64; 307 Float64Registers[i] = Entry.IsFP64;
308 VectorRegisters[i] = Entry.IsVec128; 308 VectorRegisters[i] = Entry.IsVec128;
309 RegisterAliases[i].resize(RegARM32::Reg_NUM); 309 RegisterAliases[i].resize(RegARM32::Reg_NUM);
310 // TODO(eholk): It would be better to store a QtoS flag in the 310 // TODO(eholk): It would be better to store a QtoS flag in the
311 // IceRegistersARM32 table than to compare their encodings here. 311 // IceRegistersARM32 table than to compare their encodings here.
312 QtoSRegisters[i] = Entry.IsVec128 && Entry.Encoding < EncodedReg_q8; 312 QtoSRegisters[i] = Entry.IsVec128 && Entry.Encoding < EncodedReg_q8;
313 for (int j = 0; j < Entry.NumAliases; ++j) { 313 for (int j = 0; j < Entry.NumAliases; ++j) {
314 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); 314 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]);
315 RegisterAliases[i].set(Entry.Aliases[j]); 315 RegisterAliases[i].set(Entry.Aliases[j]);
316 } 316 }
317 assert(RegisterAliases[i][i]); 317 assert(RegisterAliases[i][i]);
318 if (Entry.CCArg <= 0) { 318 if (Entry.CCArg <= 0) {
319 continue; 319 continue;
320 } 320 }
321 const auto RegNum = RegNumT::fromInt(i);
321 if (Entry.IsGPR) { 322 if (Entry.IsGPR) {
322 GPRArgInitializer[Entry.CCArg - 1] = i; 323 GPRArgInitializer[Entry.CCArg - 1] = RegNum;
323 } else if (Entry.IsI64Pair) { 324 } else if (Entry.IsI64Pair) {
324 I64ArgInitializer[Entry.CCArg - 1] = i; 325 I64ArgInitializer[Entry.CCArg - 1] = RegNum;
325 } else if (Entry.IsFP32) { 326 } else if (Entry.IsFP32) {
326 FP32ArgInitializer[Entry.CCArg - 1] = i; 327 FP32ArgInitializer[Entry.CCArg - 1] = RegNum;
327 } else if (Entry.IsFP64) { 328 } else if (Entry.IsFP64) {
328 FP64ArgInitializer[Entry.CCArg - 1] = i; 329 FP64ArgInitializer[Entry.CCArg - 1] = RegNum;
329 } else if (Entry.IsVec128) { 330 } else if (Entry.IsVec128) {
330 Vec128ArgInitializer[Entry.CCArg - 1] = i; 331 Vec128ArgInitializer[Entry.CCArg - 1] = RegNum;
331 } 332 }
332 } 333 }
333 TypeToRegisterSet[IceType_void] = InvalidRegisters; 334 TypeToRegisterSet[IceType_void] = InvalidRegisters;
334 TypeToRegisterSet[IceType_i1] = IntegerRegisters; 335 TypeToRegisterSet[IceType_i1] = IntegerRegisters;
335 TypeToRegisterSet[IceType_i8] = IntegerRegisters; 336 TypeToRegisterSet[IceType_i8] = IntegerRegisters;
336 TypeToRegisterSet[IceType_i16] = IntegerRegisters; 337 TypeToRegisterSet[IceType_i16] = IntegerRegisters;
337 TypeToRegisterSet[IceType_i32] = IntegerRegisters; 338 TypeToRegisterSet[IceType_i32] = IntegerRegisters;
338 TypeToRegisterSet[IceType_i64] = I64PairRegisters; 339 TypeToRegisterSet[IceType_i64] = I64PairRegisters;
339 TypeToRegisterSet[IceType_f32] = Float32Registers; 340 TypeToRegisterSet[IceType_f32] = Float32Registers;
340 TypeToRegisterSet[IceType_f64] = Float64Registers; 341 TypeToRegisterSet[IceType_f64] = Float64Registers;
341 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 342 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
342 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 343 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
343 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 344 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
344 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 345 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
345 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 346 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
346 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 347 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
347 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 348 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
348 TypeToRegisterSet[RegARM32::RCARM32_QtoS] = QtoSRegisters; 349 TypeToRegisterSet[RegARM32::RCARM32_QtoS] = QtoSRegisters;
349 350
350 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) 351 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i)
351 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; 352 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i];
352 353
353 filterTypeToRegisterSet( 354 filterTypeToRegisterSet(
354 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, 355 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet,
355 llvm::array_lengthof(TypeToRegisterSet), [](int32_t RegNum) -> IceString { 356 llvm::array_lengthof(TypeToRegisterSet), [](RegNumT RegNum) -> IceString {
356 // This function simply removes ", " from the register name. 357 // This function simply removes ", " from the register name.
357 IceString Name = RegARM32::getRegName(RegNum); 358 IceString Name = RegARM32::getRegName(RegNum);
358 constexpr const char RegSeparator[] = ", "; 359 constexpr const char RegSeparator[] = ", ";
359 constexpr size_t RegSeparatorWidth = 360 constexpr size_t RegSeparatorWidth =
360 llvm::array_lengthof(RegSeparator) - 1; 361 llvm::array_lengthof(RegSeparator) - 1;
361 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; 362 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos;
362 Pos = Name.find(RegSeparator)) { 363 Pos = Name.find(RegSeparator)) {
363 Name.replace(Pos, RegSeparatorWidth, ""); 364 Name.replace(Pos, RegSeparatorWidth, "");
364 } 365 }
365 return Name; 366 return Name;
366 }, getRegClassName); 367 }, getRegClassName);
367 } 368 }
368 369
369 namespace { 370 namespace {
370 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) { 371 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) {
371 for (Variable *Var : Vars) { 372 for (Variable *Var : Vars) {
372 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var); 373 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var);
373 if (!Var64) { 374 if (!Var64) {
374 // This is not the variable we are looking for. 375 // This is not the variable we are looking for.
375 continue; 376 continue;
376 } 377 }
377 assert(Var64->hasReg() || !Var64->mustHaveReg()); 378 assert(Var64->hasReg() || !Var64->mustHaveReg());
378 if (!Var64->hasReg()) { 379 if (!Var64->hasReg()) {
379 continue; 380 continue;
380 } 381 }
381 SizeT FirstReg = RegARM32::getI64PairFirstGPRNum(Var->getRegNum()); 382 const auto FirstReg =
383 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Var->getRegNum()));
382 // This assumes little endian. 384 // This assumes little endian.
383 Variable *Lo = Var64->getLo(); 385 Variable *Lo = Var64->getLo();
384 Variable *Hi = Var64->getHi(); 386 Variable *Hi = Var64->getHi();
385 assert(Lo->hasReg() == Hi->hasReg()); 387 assert(Lo->hasReg() == Hi->hasReg());
386 if (Lo->hasReg()) { 388 if (Lo->hasReg()) {
387 continue; 389 continue;
388 } 390 }
389 Lo->setRegNum(FirstReg); 391 Lo->setRegNum(FirstReg);
390 Lo->setMustHaveReg(); 392 Lo->setMustHaveReg();
391 Hi->setRegNum(FirstReg + 1); 393 Hi->setRegNum(RegNumT::fixme(FirstReg + 1));
392 Hi->setMustHaveReg(); 394 Hi->setMustHaveReg();
393 } 395 }
394 } 396 }
395 } // end of anonymous namespace 397 } // end of anonymous namespace
396 398
397 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { 399 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
398 TargetARM32::CallingConv CC; 400 TargetARM32::CallingConv CC;
399 int32_t DummyReg; 401 RegNumT DummyReg;
400 size_t OutArgsSizeBytes = 0; 402 size_t OutArgsSizeBytes = 0;
401 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { 403 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
402 Operand *Arg = legalizeUndef(Call->getArg(i)); 404 Operand *Arg = legalizeUndef(Call->getArg(i));
403 const Type Ty = Arg->getType(); 405 const Type Ty = Arg->getType();
404 if (isScalarIntegerType(Ty)) { 406 if (isScalarIntegerType(Ty)) {
405 if (CC.argInGPR(Ty, &DummyReg)) { 407 if (CC.argInGPR(Ty, &DummyReg)) {
406 continue; 408 continue;
407 } 409 }
408 } else { 410 } else {
409 if (CC.argInVFP(Ty, &DummyReg)) { 411 if (CC.argInVFP(Ty, &DummyReg)) {
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 return ARM32_STACK_ALIGNMENT_BYTES; 915 return ARM32_STACK_ALIGNMENT_BYTES;
914 } 916 }
915 917
916 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { 918 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
917 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { 919 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) {
918 return Br->optimizeBranch(NextNode); 920 return Br->optimizeBranch(NextNode);
919 } 921 }
920 return false; 922 return false;
921 } 923 }
922 924
923 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { 925 IceString TargetARM32::getRegName(RegNumT RegNum, Type Ty) const {
924 assert(RegNum < RegARM32::Reg_NUM);
925 (void)Ty; 926 (void)Ty;
926 return RegARM32::getRegName(RegNum); 927 return RegARM32::getRegName(RegNum);
927 } 928 }
928 929
929 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { 930 Variable *TargetARM32::getPhysicalRegister(RegNumT RegNum, Type Ty) {
930 static const Type DefaultType[] = { 931 static const Type DefaultType[] = {
931 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 932 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
932 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 933 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
933 (isFP32) \ 934 (isFP32) \
934 ? IceType_f32 \ 935 ? IceType_f32 \
935 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), 936 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))),
936 REGARM32_TABLE 937 REGARM32_TABLE
937 #undef X 938 #undef X
938 }; 939 };
939 940
940 assert(RegNum < RegARM32::Reg_NUM);
941 if (Ty == IceType_void) { 941 if (Ty == IceType_void) {
942 assert(RegNum < llvm::array_lengthof(DefaultType)); 942 assert(unsigned(RegNum) < llvm::array_lengthof(DefaultType));
943 Ty = DefaultType[RegNum]; 943 Ty = DefaultType[RegNum];
944 } 944 }
945 if (PhysicalRegisters[Ty].empty()) 945 if (PhysicalRegisters[Ty].empty())
946 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); 946 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM);
947 assert(RegNum < PhysicalRegisters[Ty].size()); 947 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size());
948 Variable *Reg = PhysicalRegisters[Ty][RegNum]; 948 Variable *Reg = PhysicalRegisters[Ty][RegNum];
949 if (Reg == nullptr) { 949 if (Reg == nullptr) {
950 Reg = Func->makeVariable(Ty); 950 Reg = Func->makeVariable(Ty);
951 Reg->setRegNum(RegNum); 951 Reg->setRegNum(RegNum);
952 PhysicalRegisters[Ty][RegNum] = Reg; 952 PhysicalRegisters[Ty][RegNum] = Reg;
953 // Specially mark a named physical register as an "argument" so that it is 953 // Specially mark a named physical register as an "argument" so that it is
954 // considered live upon function entry. Otherwise it's possible to get 954 // considered live upon function entry. Otherwise it's possible to get
955 // liveness validation errors for saving callee-save registers. 955 // liveness validation errors for saving callee-save registers.
956 Func->addImplicitArg(Reg); 956 Func->addImplicitArg(Reg);
957 // Don't bother tracking the live range of a named physical register. 957 // Don't bother tracking the live range of a named physical register.
(...skipping 16 matching lines...) Expand all
974 Str << getRegName(Var->getRegNum(), Var->getType()); 974 Str << getRegName(Var->getRegNum(), Var->getType());
975 return; 975 return;
976 } 976 }
977 if (Var->mustHaveReg()) { 977 if (Var->mustHaveReg()) {
978 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + 978 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) +
979 ") has no register assigned - function " + 979 ") has no register assigned - function " +
980 Func->getFunctionName()); 980 Func->getFunctionName());
981 } 981 }
982 assert(!Var->isRematerializable()); 982 assert(!Var->isRematerializable());
983 int32_t Offset = Var->getStackOffset(); 983 int32_t Offset = Var->getStackOffset();
984 int32_t BaseRegNum = Var->getBaseRegNum(); 984 auto BaseRegNum = Var->getBaseRegNum();
985 if (BaseRegNum == Variable::NoRegister) { 985 if (BaseRegNum == RegNumT::NoRegister) {
986 BaseRegNum = getFrameOrStackReg(); 986 BaseRegNum = getFrameOrStackReg();
987 } 987 }
988 const Type VarTy = Var->getType(); 988 const Type VarTy = Var->getType();
989 Str << "[" << getRegName(BaseRegNum, VarTy); 989 Str << "[" << getRegName(BaseRegNum, VarTy);
990 if (Offset != 0) { 990 if (Offset != 0) {
991 Str << ", #" << Offset; 991 Str << ", #" << Offset;
992 } 992 }
993 Str << "]"; 993 Str << "]";
994 } 994 }
995 995
996 TargetARM32::CallingConv::CallingConv() 996 TargetARM32::CallingConv::CallingConv()
997 : GPRegsUsed(RegARM32::Reg_NUM), 997 : GPRegsUsed(RegARM32::Reg_NUM),
998 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), 998 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
999 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), 999 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
1000 VFPRegsUsed(RegARM32::Reg_NUM), 1000 VFPRegsUsed(RegARM32::Reg_NUM),
1001 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), 1001 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
1002 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), 1002 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()),
1003 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} 1003 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {}
1004 1004
1005 bool TargetARM32::CallingConv::argInGPR(Type Ty, int32_t *Reg) { 1005 bool TargetARM32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) {
1006 CfgVector<SizeT> *Source; 1006 CfgVector<RegNumT> *Source;
1007 1007
1008 switch (Ty) { 1008 switch (Ty) {
1009 default: { 1009 default: {
1010 assert(isScalarIntegerType(Ty)); 1010 assert(isScalarIntegerType(Ty));
1011 Source = &GPRArgs; 1011 Source = &GPRArgs;
1012 } break; 1012 } break;
1013 case IceType_i64: { 1013 case IceType_i64: {
1014 Source = &I64Args; 1014 Source = &I64Args;
1015 } break; 1015 } break;
1016 } 1016 }
(...skipping 13 matching lines...) Expand all
1030 GPRegsUsed |= RegisterAliases[*Reg]; 1030 GPRegsUsed |= RegisterAliases[*Reg];
1031 return true; 1031 return true;
1032 } 1032 }
1033 1033
1034 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, 1034 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64,
1035 // i32) will have the first argument in r0, the second in r1-r2, and the third 1035 // i32) will have the first argument in r0, the second in r1-r2, and the third
1036 // on the stack. To model this behavior, whenever we pop a register from Regs, 1036 // on the stack. To model this behavior, whenever we pop a register from Regs,
1037 // we remove all of its aliases from the pool of available GPRs. This has the 1037 // we remove all of its aliases from the pool of available GPRs. This has the
1038 // effect of computing the "closure" on the GPR registers. 1038 // effect of computing the "closure" on the GPR registers.
1039 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( 1039 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases(
1040 CfgVector<SizeT> *Regs) { 1040 CfgVector<RegNumT> *Regs) {
1041 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { 1041 while (!Regs->empty() && GPRegsUsed[Regs->back()]) {
1042 GPRegsUsed |= RegisterAliases[Regs->back()]; 1042 GPRegsUsed |= RegisterAliases[Regs->back()];
1043 Regs->pop_back(); 1043 Regs->pop_back();
1044 } 1044 }
1045 } 1045 }
1046 1046
1047 bool TargetARM32::CallingConv::argInVFP(Type Ty, int32_t *Reg) { 1047 bool TargetARM32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) {
1048 CfgVector<SizeT> *Source; 1048 CfgVector<RegNumT> *Source;
1049 1049
1050 switch (Ty) { 1050 switch (Ty) {
1051 default: { 1051 default: {
1052 assert(isVectorType(Ty)); 1052 assert(isVectorType(Ty));
1053 Source = &Vec128Args; 1053 Source = &Vec128Args;
1054 } break; 1054 } break;
1055 case IceType_f32: { 1055 case IceType_f32: {
1056 Source = &FP32Args; 1056 Source = &FP32Args;
1057 } break; 1057 } break;
1058 case IceType_f64: { 1058 case IceType_f64: {
1059 Source = &FP64Args; 1059 Source = &FP64Args;
1060 } break; 1060 } break;
1061 } 1061 }
1062 1062
1063 discardUnavailableVFPRegs(Source); 1063 discardUnavailableVFPRegs(Source);
1064 1064
1065 if (Source->empty()) { 1065 if (Source->empty()) {
1066 VFPRegsUsed.set(); 1066 VFPRegsUsed.set();
1067 return false; 1067 return false;
1068 } 1068 }
1069 1069
1070 *Reg = Source->back(); 1070 *Reg = Source->back();
1071 VFPRegsUsed |= RegisterAliases[*Reg]; 1071 VFPRegsUsed |= RegisterAliases[*Reg];
1072 return true; 1072 return true;
1073 } 1073 }
1074 1074
1075 // Arguments in VFP registers are not packed, so we don't mark the popped 1075 // Arguments in VFP registers are not packed, so we don't mark the popped
1076 // registers' aliases as unavailable. 1076 // registers' aliases as unavailable.
1077 void TargetARM32::CallingConv::discardUnavailableVFPRegs( 1077 void TargetARM32::CallingConv::discardUnavailableVFPRegs(
1078 CfgVector<SizeT> *Regs) { 1078 CfgVector<RegNumT> *Regs) {
1079 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { 1079 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) {
1080 Regs->pop_back(); 1080 Regs->pop_back();
1081 } 1081 }
1082 } 1082 }
1083 1083
1084 void TargetARM32::lowerArguments() { 1084 void TargetARM32::lowerArguments() {
1085 VarList &Args = Func->getArgs(); 1085 VarList &Args = Func->getArgs();
1086 TargetARM32::CallingConv CC; 1086 TargetARM32::CallingConv CC;
1087 1087
1088 // For each register argument, replace Arg in the argument list with the home 1088 // For each register argument, replace Arg in the argument list with the home
1089 // register. Then generate an instruction in the prolog to copy the home 1089 // register. Then generate an instruction in the prolog to copy the home
1090 // register to the assigned location of Arg. 1090 // register to the assigned location of Arg.
1091 Context.init(Func->getEntryNode()); 1091 Context.init(Func->getEntryNode());
1092 Context.setInsertPoint(Context.getCur()); 1092 Context.setInsertPoint(Context.getCur());
1093 1093
1094 for (SizeT I = 0, E = Args.size(); I < E; ++I) { 1094 for (SizeT I = 0, E = Args.size(); I < E; ++I) {
1095 Variable *Arg = Args[I]; 1095 Variable *Arg = Args[I];
1096 Type Ty = Arg->getType(); 1096 Type Ty = Arg->getType();
1097 int RegNum; 1097 RegNumT RegNum;
1098 if (isScalarIntegerType(Ty)) { 1098 if (isScalarIntegerType(Ty)) {
1099 if (!CC.argInGPR(Ty, &RegNum)) { 1099 if (!CC.argInGPR(Ty, &RegNum)) {
1100 continue; 1100 continue;
1101 } 1101 }
1102 } else { 1102 } else {
1103 if (!CC.argInVFP(Ty, &RegNum)) { 1103 if (!CC.argInVFP(Ty, &RegNum)) {
1104 continue; 1104 continue;
1105 } 1105 }
1106 } 1106 }
1107 1107
1108 Variable *RegisterArg = Func->makeVariable(Ty); 1108 Variable *RegisterArg = Func->makeVariable(Ty);
1109 if (BuildDefs::dump()) { 1109 if (BuildDefs::dump()) {
1110 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 1110 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
1111 } 1111 }
1112 RegisterArg->setIsArg(); 1112 RegisterArg->setIsArg();
1113 Arg->setIsArg(false); 1113 Arg->setIsArg(false);
1114 Args[I] = RegisterArg; 1114 Args[I] = RegisterArg;
1115 switch (Ty) { 1115 switch (Ty) {
1116 default: { RegisterArg->setRegNum(RegNum); } break; 1116 default: { RegisterArg->setRegNum(RegNum); } break;
1117 case IceType_i64: { 1117 case IceType_i64: {
1118 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); 1118 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg);
1119 RegisterArg64->initHiLo(Func); 1119 RegisterArg64->initHiLo(Func);
1120 RegisterArg64->getLo()->setRegNum( 1120 RegisterArg64->getLo()->setRegNum(
1121 RegARM32::getI64PairFirstGPRNum(RegNum)); 1121 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(RegNum)));
1122 RegisterArg64->getHi()->setRegNum( 1122 RegisterArg64->getHi()->setRegNum(
1123 RegARM32::getI64PairSecondGPRNum(RegNum)); 1123 RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(RegNum)));
1124 } break; 1124 } break;
1125 } 1125 }
1126 Context.insert<InstAssign>(Arg, RegisterArg); 1126 Context.insert<InstAssign>(Arg, RegisterArg);
1127 } 1127 }
1128 } 1128 }
1129 1129
1130 // Helper function for addProlog(). 1130 // Helper function for addProlog().
1131 // 1131 //
1132 // This assumes Arg is an argument passed on the stack. This sets the frame 1132 // This assumes Arg is an argument passed on the stack. This sets the frame
1133 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an 1133 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 &PreservedSRegs)}; 1298 &PreservedSRegs)};
1299 for (const auto &RegClass : RegClasses) { 1299 for (const auto &RegClass : RegClasses) {
1300 const uint32_t FirstRegInClass = std::get<0>(RegClass); 1300 const uint32_t FirstRegInClass = std::get<0>(RegClass);
1301 const uint32_t LastRegInClass = std::get<1>(RegClass); 1301 const uint32_t LastRegInClass = std::get<1>(RegClass);
1302 VarList *const PreservedRegsInClass = std::get<2>(RegClass); 1302 VarList *const PreservedRegsInClass = std::get<2>(RegClass);
1303 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) { 1303 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) {
1304 if (!ToPreserve[Reg]) { 1304 if (!ToPreserve[Reg]) {
1305 continue; 1305 continue;
1306 } 1306 }
1307 ++NumCallee; 1307 ++NumCallee;
1308 Variable *PhysicalRegister = getPhysicalRegister(Reg); 1308 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg));
1309 PreservedRegsSizeBytes += 1309 PreservedRegsSizeBytes +=
1310 typeWidthInBytesOnStack(PhysicalRegister->getType()); 1310 typeWidthInBytesOnStack(PhysicalRegister->getType());
1311 PreservedRegsInClass->push_back(PhysicalRegister); 1311 PreservedRegsInClass->push_back(PhysicalRegister);
1312 } 1312 }
1313 } 1313 }
1314 1314
1315 Ctx->statsUpdateRegistersSaved(NumCallee); 1315 Ctx->statsUpdateRegistersSaved(NumCallee);
1316 if (!PreservedSRegs.empty()) 1316 if (!PreservedSRegs.empty())
1317 _push(PreservedSRegs); 1317 _push(PreservedSRegs);
1318 if (!PreservedGPRs.empty()) 1318 if (!PreservedGPRs.empty())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 // Arg[0] is closest to the stack/frame pointer. 1373 // Arg[0] is closest to the stack/frame pointer.
1374 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); 1374 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg());
1375 size_t BasicFrameOffset = PreservedRegsSizeBytes; 1375 size_t BasicFrameOffset = PreservedRegsSizeBytes;
1376 if (!UsesFramePointer) 1376 if (!UsesFramePointer)
1377 BasicFrameOffset += SpillAreaSizeBytes; 1377 BasicFrameOffset += SpillAreaSizeBytes;
1378 1378
1379 const VarList &Args = Func->getArgs(); 1379 const VarList &Args = Func->getArgs();
1380 size_t InArgsSizeBytes = 0; 1380 size_t InArgsSizeBytes = 0;
1381 TargetARM32::CallingConv CC; 1381 TargetARM32::CallingConv CC;
1382 for (Variable *Arg : Args) { 1382 for (Variable *Arg : Args) {
1383 int32_t DummyReg; 1383 RegNumT DummyReg;
1384 const Type Ty = Arg->getType(); 1384 const Type Ty = Arg->getType();
1385 1385
1386 // Skip arguments passed in registers. 1386 // Skip arguments passed in registers.
1387 if (isScalarIntegerType(Ty)) { 1387 if (isScalarIntegerType(Ty)) {
1388 if (CC.argInGPR(Ty, &DummyReg)) { 1388 if (CC.argInGPR(Ty, &DummyReg)) {
1389 continue; 1389 continue;
1390 } 1390 }
1391 } else { 1391 } else {
1392 if (CC.argInVFP(Ty, &DummyReg)) { 1392 if (CC.argInVFP(Ty, &DummyReg)) {
1393 continue; 1393 continue;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 1492
1493 RI->setDeleted(); 1493 RI->setDeleted();
1494 } 1494 }
1495 1495
1496 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { 1496 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const {
1497 constexpr bool ZeroExt = false; 1497 constexpr bool ZeroExt = false;
1498 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); 1498 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset);
1499 } 1499 }
1500 1500
1501 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( 1501 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister(
1502 Variable *Base, int32_t Offset, int32_t ScratchRegNum) { 1502 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) {
1503 // Legalize will likely need a movw/movt combination, but if the top bits are 1503 // Legalize will likely need a movw/movt combination, but if the top bits are
1504 // all 0 from negating the offset and subtracting, we could use that instead. 1504 // all 0 from negating the offset and subtracting, we could use that instead.
1505 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; 1505 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0;
1506 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); 1506 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum);
1507 if (ShouldSub) { 1507 if (ShouldSub) {
1508 Operand *OffsetVal = 1508 Operand *OffsetVal =
1509 Target->legalize(Target->Ctx->getConstantInt32(-Offset), 1509 Target->legalize(Target->Ctx->getConstantInt32(-Offset),
1510 Legal_Reg | Legal_Flex, ScratchRegNum); 1510 Legal_Reg | Legal_Flex, ScratchRegNum);
1511 Target->_sub(ScratchReg, Base, OffsetVal); 1511 Target->_sub(ScratchReg, Base, OffsetVal);
1512 } else { 1512 } else {
1513 Operand *OffsetVal = 1513 Operand *OffsetVal =
1514 Target->legalize(Target->Ctx->getConstantInt32(Offset), 1514 Target->legalize(Target->Ctx->getConstantInt32(Offset),
1515 Legal_Reg | Legal_Flex, ScratchRegNum); 1515 Legal_Reg | Legal_Flex, ScratchRegNum);
1516 Target->_add(ScratchReg, Base, OffsetVal); 1516 Target->_add(ScratchReg, Base, OffsetVal);
1517 } 1517 }
1518 1518
1519 if (ScratchRegNum == Target->getReservedTmpReg()) { 1519 if (ScratchRegNum == Target->getReservedTmpReg()) {
1520 const bool BaseIsStackOrFramePtr = 1520 const bool BaseIsStackOrFramePtr =
1521 Base->getRegNum() == static_cast<int32_t>(Target->getFrameOrStackReg()); 1521 Base->getRegNum() == Target->getFrameOrStackReg();
1522 // There is currently no code path that would trigger this assertion, so we 1522 // There is currently no code path that would trigger this assertion, so we
1523 // leave this assertion here in case it is ever violated. This is not a 1523 // leave this assertion here in case it is ever violated. This is not a
1524 // fatal error (thus the use of assert() and not llvm::report_fatal_error) 1524 // fatal error (thus the use of assert() and not llvm::report_fatal_error)
1525 // as the program compiled by subzero will still work correctly. 1525 // as the program compiled by subzero will still work correctly.
1526 assert(BaseIsStackOrFramePtr); 1526 assert(BaseIsStackOrFramePtr);
1527 // Side-effect: updates TempBase to reflect the new Temporary. 1527 // Side-effect: updates TempBase to reflect the new Temporary.
1528 if (BaseIsStackOrFramePtr) { 1528 if (BaseIsStackOrFramePtr) {
1529 TempBaseReg = ScratchReg; 1529 TempBaseReg = ScratchReg;
1530 TempBaseOffset = Offset; 1530 TempBaseOffset = Offset;
1531 } else { 1531 } else {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 MovInstr->getPredicate()); 1618 MovInstr->getPredicate());
1619 // _str() does not have a Dest, so we add a fake-def(Dest). 1619 // _str() does not have a Dest, so we add a fake-def(Dest).
1620 Target->Context.insert<InstFakeDef>(Dest); 1620 Target->Context.insert<InstFakeDef>(Dest);
1621 Legalized = true; 1621 Legalized = true;
1622 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1622 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1623 if (Var->isRematerializable()) { 1623 if (Var->isRematerializable()) {
1624 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1624 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1625 1625
1626 // ExtraOffset is only needed for frame-pointer based frames as we have 1626 // ExtraOffset is only needed for frame-pointer based frames as we have
1627 // to account for spill storage. 1627 // to account for spill storage.
1628 const int32_t ExtraOffset = 1628 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg())
1629 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) 1629 ? Target->getFrameFixedAllocaOffset()
1630 ? Target->getFrameFixedAllocaOffset() 1630 : 0;
1631 : 0;
1632 1631
1633 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1632 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1634 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1633 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1635 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1634 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1636 Target->_mov(Dest, T); 1635 Target->_mov(Dest, T);
1637 Legalized = true; 1636 Legalized = true;
1638 } else { 1637 } else {
1639 if (!Var->hasReg()) { 1638 if (!Var->hasReg()) {
1640 // This is a _mov(Variable, Mem()), i.e., a load. 1639 // This is a _mov(Variable, Mem()), i.e., a load.
1641 const int32_t Offset = Var->getStackOffset(); 1640 const int32_t Offset = Var->getStackOffset();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 bool AllowOffsets) { 1688 bool AllowOffsets) {
1690 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); 1689 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable());
1691 assert( 1690 assert(
1692 Mem->isRegReg() || 1691 Mem->isRegReg() ||
1693 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); 1692 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue()));
1694 1693
1695 bool Legalized = false; 1694 bool Legalized = false;
1696 Variable *Base = Mem->getBase(); 1695 Variable *Base = Mem->getBase();
1697 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); 1696 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue();
1698 if (Base->isRematerializable()) { 1697 if (Base->isRematerializable()) {
1699 const int32_t ExtraOffset = 1698 const int32_t ExtraOffset = (Base->getRegNum() == Target->getFrameReg())
1700 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg()) 1699 ? Target->getFrameFixedAllocaOffset()
1701 ? Target->getFrameFixedAllocaOffset() 1700 : 0;
1702 : 0;
1703 Offset += Base->getStackOffset() + ExtraOffset; 1701 Offset += Base->getStackOffset() + ExtraOffset;
1704 Base = Target->getPhysicalRegister(Base->getRegNum()); 1702 Base = Target->getPhysicalRegister(Base->getRegNum());
1705 assert(!Base->isRematerializable()); 1703 assert(!Base->isRematerializable());
1706 Legalized = true; 1704 Legalized = true;
1707 } 1705 }
1708 1706
1709 if (!Legalized && !Target->NeedSandboxing) { 1707 if (!Legalized && !Target->NeedSandboxing) {
1710 return nullptr; 1708 return nullptr;
1711 } 1709 }
1712 1710
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 } 1910 }
1913 } 1911 }
1914 llvm::report_fatal_error("Unsupported operand type"); 1912 llvm::report_fatal_error("Unsupported operand type");
1915 return nullptr; 1913 return nullptr;
1916 } 1914 }
1917 1915
1918 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, 1916 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include,
1919 RegSetMask Exclude) const { 1917 RegSetMask Exclude) const {
1920 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); 1918 llvm::SmallBitVector Registers(RegARM32::Reg_NUM);
1921 1919
1922 for (int32_t i = 0; i < RegARM32::Reg_NUM; ++i) { 1920 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) {
1923 const auto &Entry = RegARM32::RegTable[i]; 1921 const auto &Entry = RegARM32::RegTable[i];
1924 if (Entry.Scratch && (Include & RegSet_CallerSave)) 1922 if (Entry.Scratch && (Include & RegSet_CallerSave))
1925 Registers[i] = true; 1923 Registers[i] = true;
1926 if (Entry.Preserved && (Include & RegSet_CalleeSave)) 1924 if (Entry.Preserved && (Include & RegSet_CalleeSave))
1927 Registers[i] = true; 1925 Registers[i] = true;
1928 if (Entry.StackPtr && (Include & RegSet_StackPointer)) 1926 if (Entry.StackPtr && (Include & RegSet_StackPointer))
1929 Registers[i] = true; 1927 Registers[i] = true;
1930 if (Entry.FramePtr && (Include & RegSet_FramePointer)) 1928 if (Entry.FramePtr && (Include & RegSet_FramePointer))
1931 Registers[i] = true; 1929 Registers[i] = true;
1932 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) 1930 if (Entry.Scratch && (Exclude & RegSet_CallerSave))
(...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after
3376 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { 3374 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) {
3377 (this->*TargetHelperPreamble->second)(Instr); 3375 (this->*TargetHelperPreamble->second)(Instr);
3378 } 3376 }
3379 } 3377 }
3380 MaybeLeafFunc = false; 3378 MaybeLeafFunc = false;
3381 NeedsStackAlignment = true; 3379 NeedsStackAlignment = true;
3382 3380
3383 // Assign arguments to registers and stack. Also reserve stack. 3381 // Assign arguments to registers and stack. Also reserve stack.
3384 TargetARM32::CallingConv CC; 3382 TargetARM32::CallingConv CC;
3385 // Pair of Arg Operand -> GPR number assignments. 3383 // Pair of Arg Operand -> GPR number assignments.
3386 llvm::SmallVector<std::pair<Operand *, int32_t>, NumGPRArgs> GPRArgs; 3384 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumGPRArgs> GPRArgs;
3387 llvm::SmallVector<std::pair<Operand *, int32_t>, NumFP32Args> FPArgs; 3385 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumFP32Args> FPArgs;
3388 // Pair of Arg Operand -> stack offset. 3386 // Pair of Arg Operand -> stack offset.
3389 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; 3387 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
3390 size_t ParameterAreaSizeBytes = 0; 3388 size_t ParameterAreaSizeBytes = 0;
3391 3389
3392 // Classify each argument operand according to the location where the 3390 // Classify each argument operand according to the location where the
3393 // argument is passed. 3391 // argument is passed.
3394 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { 3392 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
3395 Operand *Arg = legalizeUndef(Instr->getArg(i)); 3393 Operand *Arg = legalizeUndef(Instr->getArg(i));
3396 const Type Ty = Arg->getType(); 3394 const Type Ty = Arg->getType();
3397 bool InReg = false; 3395 bool InReg = false;
3398 int32_t Reg; 3396 RegNumT Reg;
3399 if (isScalarIntegerType(Ty)) { 3397 if (isScalarIntegerType(Ty)) {
3400 InReg = CC.argInGPR(Ty, &Reg); 3398 InReg = CC.argInGPR(Ty, &Reg);
3401 } else { 3399 } else {
3402 InReg = CC.argInVFP(Ty, &Reg); 3400 InReg = CC.argInVFP(Ty, &Reg);
3403 } 3401 }
3404 3402
3405 if (!InReg) { 3403 if (!InReg) {
3406 ParameterAreaSizeBytes = 3404 ParameterAreaSizeBytes =
3407 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); 3405 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
3408 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); 3406 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
3409 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); 3407 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
3410 continue; 3408 continue;
3411 } 3409 }
3412 3410
3413 if (Ty == IceType_i64) { 3411 if (Ty == IceType_i64) {
3414 Operand *Lo = loOperand(Arg); 3412 Operand *Lo = loOperand(Arg);
3415 Operand *Hi = hiOperand(Arg); 3413 Operand *Hi = hiOperand(Arg);
3416 GPRArgs.push_back( 3414 GPRArgs.push_back(std::make_pair(
3417 std::make_pair(Lo, RegARM32::getI64PairFirstGPRNum(Reg))); 3415 Lo, RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Reg))));
3418 GPRArgs.push_back( 3416 GPRArgs.push_back(std::make_pair(
3419 std::make_pair(Hi, RegARM32::getI64PairSecondGPRNum(Reg))); 3417 Hi, RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(Reg))));
3420 } else if (isScalarIntegerType(Ty)) { 3418 } else if (isScalarIntegerType(Ty)) {
3421 GPRArgs.push_back(std::make_pair(Arg, Reg)); 3419 GPRArgs.push_back(std::make_pair(Arg, Reg));
3422 } else { 3420 } else {
3423 FPArgs.push_back(std::make_pair(Arg, Reg)); 3421 FPArgs.push_back(std::make_pair(Arg, Reg));
3424 } 3422 }
3425 } 3423 }
3426 3424
3427 // Adjust the parameter area so that the stack is aligned. It is assumed that 3425 // Adjust the parameter area so that the stack is aligned. It is assumed that
3428 // the stack is already aligned at the start of the calling sequence. 3426 // the stack is already aligned at the start of the calling sequence.
3429 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); 3427 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
(...skipping 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after
5511 } 5509 }
5512 5510
5513 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { 5511 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) {
5514 _trap(); 5512 _trap();
5515 } 5513 }
5516 5514
5517 void TargetARM32::prelowerPhis() { 5515 void TargetARM32::prelowerPhis() {
5518 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); 5516 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func);
5519 } 5517 }
5520 5518
5521 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { 5519 Variable *TargetARM32::makeVectorOfZeros(Type Ty, RegNumT RegNum) {
5522 Variable *Reg = makeReg(Ty, RegNum); 5520 Variable *Reg = makeReg(Ty, RegNum);
5523 Context.insert<InstFakeDef>(Reg); 5521 Context.insert<InstFakeDef>(Reg);
5524 assert(isVectorType(Ty)); 5522 assert(isVectorType(Ty));
5525 _veor(Reg, Reg, Reg); 5523 _veor(Reg, Reg, Reg);
5526 return Reg; 5524 return Reg;
5527 } 5525 }
5528 5526
5529 // Helper for legalize() to emit the right code to lower an operand to a 5527 // Helper for legalize() to emit the right code to lower an operand to a
5530 // register of the appropriate type. 5528 // register of the appropriate type.
5531 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { 5529 Variable *TargetARM32::copyToReg(Operand *Src, RegNumT RegNum) {
5532 Type Ty = Src->getType(); 5530 Type Ty = Src->getType();
5533 Variable *Reg = makeReg(Ty, RegNum); 5531 Variable *Reg = makeReg(Ty, RegNum);
5534 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { 5532 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) {
5535 _ldr(Reg, Mem); 5533 _ldr(Reg, Mem);
5536 } else { 5534 } else {
5537 _mov(Reg, Src); 5535 _mov(Reg, Src);
5538 } 5536 }
5539 return Reg; 5537 return Reg;
5540 } 5538 }
5541 5539
5542 // TODO(jpp): remove unneeded else clauses in legalize. 5540 // TODO(jpp): remove unneeded else clauses in legalize.
5543 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, 5541 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
5544 int32_t RegNum) { 5542 RegNumT RegNum) {
5545 Type Ty = From->getType(); 5543 Type Ty = From->getType();
5546 // Assert that a physical register is allowed. To date, all calls to 5544 // Assert that a physical register is allowed. To date, all calls to
5547 // legalize() allow a physical register. Legal_Flex converts registers to the 5545 // legalize() allow a physical register. Legal_Flex converts registers to the
5548 // right type OperandARM32FlexReg as needed. 5546 // right type OperandARM32FlexReg as needed.
5549 assert(Allowed & Legal_Reg); 5547 assert(Allowed & Legal_Reg);
5550 5548
5551 // Copied ipsis literis from TargetX86Base<Machine>. 5549 // Copied ipsis literis from TargetX86Base<Machine>.
5552 if (RegNum == Variable::NoRegister) { 5550 if (RegNum == RegNumT::NoRegister) {
5553 if (Variable *Subst = getContext().availabilityGet(From)) { 5551 if (Variable *Subst = getContext().availabilityGet(From)) {
5554 // At this point we know there is a potential substitution available. 5552 // At this point we know there is a potential substitution available.
5555 if (!Subst->isRematerializable() && Subst->mustHaveReg() && 5553 if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
5556 !Subst->hasReg()) { 5554 !Subst->hasReg()) {
5557 // At this point we know the substitution will have a register. 5555 // At this point we know the substitution will have a register.
5558 if (From->getType() == Subst->getType()) { 5556 if (From->getType() == Subst->getType()) {
5559 // At this point we know the substitution's register is compatible. 5557 // At this point we know the substitution's register is compatible.
5560 return Subst; 5558 return Subst;
5561 } 5559 }
5562 } 5560 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
5726 } 5724 }
5727 // Check if the variable is guaranteed a physical register. This can happen 5725 // Check if the variable is guaranteed a physical register. This can happen
5728 // either when the variable is pre-colored or when it is assigned infinite 5726 // either when the variable is pre-colored or when it is assigned infinite
5729 // weight. 5727 // weight.
5730 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); 5728 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
5731 // We need a new physical register for the operand if: 5729 // We need a new physical register for the operand if:
5732 // Mem is not allowed and Var isn't guaranteed a physical 5730 // Mem is not allowed and Var isn't guaranteed a physical
5733 // register, or 5731 // register, or
5734 // RegNum is required and Var->getRegNum() doesn't match. 5732 // RegNum is required and Var->getRegNum() doesn't match.
5735 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 5733 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
5736 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 5734 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
5737 From = copyToReg(From, RegNum); 5735 From = copyToReg(From, RegNum);
5738 } 5736 }
5739 return From; 5737 return From;
5740 } 5738 }
5741 llvm::report_fatal_error("Unhandled operand kind in legalize()"); 5739 llvm::report_fatal_error("Unhandled operand kind in legalize()");
5742 5740
5743 return From; 5741 return From;
5744 } 5742 }
5745 5743
5746 /// Provide a trivial wrapper to legalize() for this common usage. 5744 /// Provide a trivial wrapper to legalize() for this common usage.
5747 Variable *TargetARM32::legalizeToReg(Operand *From, int32_t RegNum) { 5745 Variable *TargetARM32::legalizeToReg(Operand *From, RegNumT RegNum) {
5748 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); 5746 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
5749 } 5747 }
5750 5748
5751 /// Legalize undef values to concrete values. 5749 /// Legalize undef values to concrete values.
5752 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) { 5750 Operand *TargetARM32::legalizeUndef(Operand *From, RegNumT RegNum) {
5753 Type Ty = From->getType(); 5751 Type Ty = From->getType();
5754 if (llvm::isa<ConstantUndef>(From)) { 5752 if (llvm::isa<ConstantUndef>(From)) {
5755 // Lower undefs to zero. Another option is to lower undefs to an 5753 // Lower undefs to zero. Another option is to lower undefs to an
5756 // uninitialized register; however, using an uninitialized register results 5754 // uninitialized register; however, using an uninitialized register results
5757 // in less predictable code. 5755 // in less predictable code.
5758 // 5756 //
5759 // If in the future the implementation is changed to lower undef values to 5757 // If in the future the implementation is changed to lower undef values to
5760 // uninitialized registers, a FakeDef will be needed: 5758 // uninitialized registers, a FakeDef will be needed:
5761 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to 5759 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to
5762 // ensure that the live range of Reg is not overestimated. If the constant 5760 // ensure that the live range of Reg is not overestimated. If the constant
(...skipping 27 matching lines...) Expand all
5790 Variable64On32 *TargetARM32::makeI64RegPair() { 5788 Variable64On32 *TargetARM32::makeI64RegPair() {
5791 Variable64On32 *Reg = 5789 Variable64On32 *Reg =
5792 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 5790 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
5793 Reg->setMustHaveReg(); 5791 Reg->setMustHaveReg();
5794 Reg->initHiLo(Func); 5792 Reg->initHiLo(Func);
5795 Reg->getLo()->setMustNotHaveReg(); 5793 Reg->getLo()->setMustNotHaveReg();
5796 Reg->getHi()->setMustNotHaveReg(); 5794 Reg->getHi()->setMustNotHaveReg();
5797 return Reg; 5795 return Reg;
5798 } 5796 }
5799 5797
5800 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { 5798 Variable *TargetARM32::makeReg(Type Type, RegNumT RegNum) {
5801 // There aren't any 64-bit integer registers for ARM32. 5799 // There aren't any 64-bit integer registers for ARM32.
5802 assert(Type != IceType_i64); 5800 assert(Type != IceType_i64);
5803 assert(AllowTemporaryWithNoReg || RegNum != Variable::NoRegister); 5801 assert(AllowTemporaryWithNoReg || RegNum != RegNumT::NoRegister);
5804 Variable *Reg = Func->makeVariable(Type); 5802 Variable *Reg = Func->makeVariable(Type);
5805 if (RegNum == Variable::NoRegister) 5803 if (RegNum == RegNumT::NoRegister)
5806 Reg->setMustHaveReg(); 5804 Reg->setMustHaveReg();
5807 else 5805 else
5808 Reg->setRegNum(RegNum); 5806 Reg->setRegNum(RegNum);
5809 return Reg; 5807 return Reg;
5810 } 5808 }
5811 5809
5812 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, 5810 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align,
5813 int32_t TmpRegNum) { 5811 RegNumT TmpRegNum) {
5814 assert(llvm::isPowerOf2_32(Align)); 5812 assert(llvm::isPowerOf2_32(Align));
5815 uint32_t RotateAmt; 5813 uint32_t RotateAmt;
5816 uint32_t Immed_8; 5814 uint32_t Immed_8;
5817 Operand *Mask; 5815 Operand *Mask;
5818 // Use AND or BIC to mask off the bits, depending on which immediate fits (if 5816 // Use AND or BIC to mask off the bits, depending on which immediate fits (if
5819 // it fits at all). Assume Align is usually small, in which case BIC works 5817 // it fits at all). Assume Align is usually small, in which case BIC works
5820 // better. Thus, this rounds down to the alignment. 5818 // better. Thus, this rounds down to the alignment.
5821 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { 5819 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) {
5822 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, 5820 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex,
5823 TmpRegNum); 5821 TmpRegNum);
5824 _bic(Reg, Reg, Mask); 5822 _bic(Reg, Reg, Mask);
5825 } else { 5823 } else {
5826 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, 5824 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex,
5827 TmpRegNum); 5825 TmpRegNum);
5828 _and(Reg, Reg, Mask); 5826 _and(Reg, Reg, Mask);
5829 } 5827 }
5830 } 5828 }
5831 5829
5832 void TargetARM32::postLower() { 5830 void TargetARM32::postLower() {
5833 if (Ctx->getFlags().getOptLevel() == Opt_m1) 5831 if (Ctx->getFlags().getOptLevel() == Opt_m1)
5834 return; 5832 return;
5835 markRedefinitions(); 5833 markRedefinitions();
5836 Context.availabilityUpdate(); 5834 Context.availabilityUpdate();
5837 } 5835 }
5838 5836
5839 void TargetARM32::makeRandomRegisterPermutation( 5837 void TargetARM32::makeRandomRegisterPermutation(
5840 llvm::SmallVectorImpl<int32_t> &Permutation, 5838 llvm::SmallVectorImpl<RegNumT> &Permutation,
5841 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 5839 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
5842 (void)Permutation; 5840 (void)Permutation;
5843 (void)ExcludeRegisters; 5841 (void)ExcludeRegisters;
5844 (void)Salt; 5842 (void)Salt;
5845 UnimplementedError(Func->getContext()->getFlags()); 5843 UnimplementedError(Func->getContext()->getFlags());
5846 } 5844 }
5847 5845
5848 void TargetARM32::emit(const ConstantInteger32 *C) const { 5846 void TargetARM32::emit(const ConstantInteger32 *C) const {
5849 if (!BuildDefs::dump()) 5847 if (!BuildDefs::dump())
5850 return; 5848 return;
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
6585 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6583 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6586 } 6584 }
6587 6585
6588 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; 6586 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM];
6589 llvm::SmallBitVector 6587 llvm::SmallBitVector
6590 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; 6588 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM];
6591 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6589 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6592 6590
6593 } // end of namespace ARM32 6591 } // end of namespace ARM32
6594 } // end of namespace Ice 6592 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringMIPS32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698