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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2313293002: [SubZero] Implement address optimization for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/mips-address-mode-opt.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 2292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 void TargetMIPS32::lowerLoad(const InstLoad *Instr) { 2303 void TargetMIPS32::lowerLoad(const InstLoad *Instr) {
2304 // A Load instruction can be treated the same as an Assign instruction, after 2304 // A Load instruction can be treated the same as an Assign instruction, after
2305 // the source operand is transformed into an OperandARM32Mem operand. 2305 // the source operand is transformed into an OperandARM32Mem operand.
2306 Type Ty = Instr->getDest()->getType(); 2306 Type Ty = Instr->getDest()->getType();
2307 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty); 2307 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty);
2308 Variable *DestLoad = Instr->getDest(); 2308 Variable *DestLoad = Instr->getDest();
2309 auto *Assign = InstAssign::create(Func, DestLoad, Src0); 2309 auto *Assign = InstAssign::create(Func, DestLoad, Src0);
2310 lowerAssign(Assign); 2310 lowerAssign(Assign);
2311 } 2311 }
2312 2312
2313 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); } 2313 namespace {
2314 void dumpAddressOpt(const Cfg *Func, const Variable *Base, int32_t Offset,
2315 const Inst *Reason) {
2316 if (!BuildDefs::dump())
2317 return;
2318 if (!Func->isVerbose(IceV_AddrOpt))
2319 return;
2320 OstreamLocker _(Func->getContext());
2321 Ostream &Str = Func->getContext()->getStrDump();
2322 Str << "Instruction: ";
2323 Reason->dumpDecorated(Func);
2324 Str << " results in Base=";
2325 if (Base)
2326 Base->dump(Func);
2327 else
2328 Str << "<null>";
2329 Str << ", Offset=" << Offset << "\n";
2330 }
2331
2332 bool matchAssign(const VariablesMetadata *VMetadata, Variable **Var,
2333 int32_t *Offset, const Inst **Reason) {
2334 // Var originates from Var=SrcVar ==> set Var:=SrcVar
2335 if (*Var == nullptr)
2336 return false;
2337 const Inst *VarAssign = VMetadata->getSingleDefinition(*Var);
2338 if (!VarAssign)
2339 return false;
2340 assert(!VMetadata->isMultiDef(*Var));
2341 if (!llvm::isa<InstAssign>(VarAssign))
2342 return false;
2343
2344 Operand *SrcOp = VarAssign->getSrc(0);
2345 bool Optimized = false;
2346 if (auto *SrcVar = llvm::dyn_cast<Variable>(SrcOp)) {
2347 if (!VMetadata->isMultiDef(SrcVar) ||
2348 // TODO: ensure SrcVar stays single-BB
2349 false) {
2350 Optimized = true;
2351 *Var = SrcVar;
2352 } else if (auto *Const = llvm::dyn_cast<ConstantInteger32>(SrcOp)) {
2353 int32_t MoreOffset = Const->getValue();
2354 int32_t NewOffset = MoreOffset + *Offset;
2355 if (Utils::WouldOverflowAdd(*Offset, MoreOffset))
2356 return false;
2357 *Var = nullptr;
2358 *Offset += NewOffset;
2359 Optimized = true;
2360 }
2361 }
2362
2363 if (Optimized) {
2364 *Reason = VarAssign;
2365 }
2366
2367 return Optimized;
2368 }
2369
2370 bool isAddOrSub(const Inst *Instr, InstArithmetic::OpKind *Kind) {
2371 if (const auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) {
2372 switch (Arith->getOp()) {
2373 default:
2374 return false;
2375 case InstArithmetic::Add:
2376 case InstArithmetic::Sub:
2377 *Kind = Arith->getOp();
2378 return true;
2379 }
2380 }
2381 return false;
2382 }
2383
2384 bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable **Base,
2385 int32_t *Offset, const Inst **Reason) {
2386 // Base is Base=Var+Const || Base is Base=Const+Var ==>
2387 // set Base=Var, Offset+=Const
2388 // Base is Base=Var-Const ==>
2389 // set Base=Var, Offset-=Const
2390 if (*Base == nullptr)
2391 return false;
2392 const Inst *BaseInst = VMetadata->getSingleDefinition(*Base);
2393 if (BaseInst == nullptr) {
2394 return false;
2395 }
2396 assert(!VMetadata->isMultiDef(*Base));
2397
2398 auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(BaseInst);
2399 if (ArithInst == nullptr)
2400 return false;
2401 InstArithmetic::OpKind Kind;
2402 if (!isAddOrSub(ArithInst, &Kind))
2403 return false;
2404 bool IsAdd = Kind == InstArithmetic::Add;
2405 Operand *Src0 = ArithInst->getSrc(0);
2406 Operand *Src1 = ArithInst->getSrc(1);
2407 auto *Var0 = llvm::dyn_cast<Variable>(Src0);
2408 auto *Var1 = llvm::dyn_cast<Variable>(Src1);
2409 auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0);
2410 auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1);
2411 Variable *NewBase = nullptr;
2412 int32_t NewOffset = *Offset;
2413
2414 if (Var0 == nullptr && Const0 == nullptr) {
2415 assert(llvm::isa<ConstantRelocatable>(Src0));
2416 return false;
2417 }
2418
2419 if (Var1 == nullptr && Const1 == nullptr) {
2420 assert(llvm::isa<ConstantRelocatable>(Src1));
2421 return false;
2422 }
2423
2424 if (Var0 && Var1)
2425 // TODO(jpp): merge base/index splitting into here.
2426 return false;
2427 if (!IsAdd && Var1)
2428 return false;
2429 if (Var0)
2430 NewBase = Var0;
2431 else if (Var1)
2432 NewBase = Var1;
2433 // Compute the updated constant offset.
2434 if (Const0) {
2435 int32_t MoreOffset = IsAdd ? Const0->getValue() : -Const0->getValue();
2436 if (Utils::WouldOverflowAdd(NewOffset, MoreOffset))
2437 return false;
2438 NewOffset += MoreOffset;
2439 }
2440 if (Const1) {
2441 int32_t MoreOffset = IsAdd ? Const1->getValue() : -Const1->getValue();
2442 if (Utils::WouldOverflowAdd(NewOffset, MoreOffset))
2443 return false;
2444 NewOffset += MoreOffset;
2445 }
2446
2447 // Update the computed address parameters once we are sure optimization
2448 // is valid.
2449 *Base = NewBase;
2450 *Offset = NewOffset;
2451 *Reason = BaseInst;
2452 return true;
2453 }
2454 } // end of anonymous namespace
2455
2456 OperandMIPS32Mem *TargetMIPS32::formAddressingMode(Type Ty, Cfg *Func,
2457 const Inst *LdSt,
2458 Operand *Base) {
2459 assert(Base != nullptr);
2460 int32_t OffsetImm = 0;
2461
2462 Func->resetCurrentNode();
2463 if (Func->isVerbose(IceV_AddrOpt)) {
2464 OstreamLocker _(Func->getContext());
2465 Ostream &Str = Func->getContext()->getStrDump();
2466 Str << "\nAddress mode formation:\t";
2467 LdSt->dumpDecorated(Func);
2468 }
2469
2470 if (isVectorType(Ty)) {
2471 UnimplementedError(getFlags());
2472 return nullptr;
2473 }
2474
2475 auto *BaseVar = llvm::dyn_cast<Variable>(Base);
2476 if (BaseVar == nullptr)
2477 return nullptr;
2478
2479 const VariablesMetadata *VMetadata = Func->getVMetadata();
2480 const Inst *Reason = nullptr;
2481
2482 do {
2483 if (Reason != nullptr) {
2484 dumpAddressOpt(Func, BaseVar, OffsetImm, Reason);
2485 Reason = nullptr;
2486 }
2487
2488 if (matchAssign(VMetadata, &BaseVar, &OffsetImm, &Reason)) {
2489 continue;
2490 }
2491
2492 if (matchOffsetBase(VMetadata, &BaseVar, &OffsetImm, &Reason)) {
2493 continue;
2494 }
2495 } while (Reason);
2496
2497 if (BaseVar == nullptr) {
2498 // We need base register rather than just OffsetImm. Move the OffsetImm to
2499 // BaseVar and form 0(BaseVar) addressing.
2500 const Type PointerType = getPointerType();
2501 BaseVar = makeReg(PointerType);
2502 Context.insert<InstAssign>(BaseVar, Ctx->getConstantInt32(OffsetImm));
2503 OffsetImm = 0;
2504 } else if (OffsetImm != 0) {
2505 // If the OffsetImm is more than signed 16-bit value then add it in the
2506 // BaseVar and form 0(BaseVar) addressing.
2507 const int32_t PositiveOffset = OffsetImm > 0 ? OffsetImm : -OffsetImm;
2508 const InstArithmetic::OpKind Op =
2509 OffsetImm > 0 ? InstArithmetic::Add : InstArithmetic::Sub;
2510 constexpr bool ZeroExt = false;
2511 if (!OperandMIPS32Mem::canHoldOffset(Ty, ZeroExt, OffsetImm)) {
2512 const Type PointerType = getPointerType();
2513 Variable *T = makeReg(PointerType);
2514 Context.insert<InstArithmetic>(Op, T, BaseVar,
2515 Ctx->getConstantInt32(PositiveOffset));
2516 BaseVar = T;
2517 OffsetImm = 0;
2518 }
2519 }
2520
2521 assert(BaseVar != nullptr);
2522 assert(OffsetImm < 0 ? (-OffsetImm & 0x0000ffff) == -OffsetImm
2523 : (OffsetImm & 0x0000ffff) == OffsetImm);
2524
2525 return OperandMIPS32Mem::create(
2526 Func, Ty, BaseVar,
2527 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(OffsetImm)));
2528 }
2529
2530 void TargetMIPS32::doAddressOptLoad() {
2531 Inst *Instr = iteratorToInst(Context.getCur());
2532 assert(llvm::isa<InstLoad>(Instr));
2533 Variable *Dest = Instr->getDest();
2534 Operand *Addr = Instr->getSrc(0);
2535 if (OperandMIPS32Mem *Mem =
2536 formAddressingMode(Dest->getType(), Func, Instr, Addr)) {
2537 Instr->setDeleted();
2538 Context.insert<InstLoad>(Dest, Mem);
2539 }
2540 }
2314 2541
2315 void TargetMIPS32::randomlyInsertNop(float Probability, 2542 void TargetMIPS32::randomlyInsertNop(float Probability,
2316 RandomNumberGenerator &RNG) { 2543 RandomNumberGenerator &RNG) {
2317 RandomNumberGeneratorWrapper RNGW(RNG); 2544 RandomNumberGeneratorWrapper RNGW(RNG);
2318 if (RNGW.getTrueWithProbability(Probability)) { 2545 if (RNGW.getTrueWithProbability(Probability)) {
2319 UnimplementedError(getFlags()); 2546 UnimplementedError(getFlags());
2320 } 2547 }
2321 } 2548 }
2322 2549
2323 void TargetMIPS32::lowerPhi(const InstPhi * /*Instr*/) { 2550 void TargetMIPS32::lowerPhi(const InstPhi * /*Instr*/) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 Variable *ValueHi = legalizeToReg(hiOperand(Value)); 2600 Variable *ValueHi = legalizeToReg(hiOperand(Value));
2374 Variable *ValueLo = legalizeToReg(loOperand(Value)); 2601 Variable *ValueLo = legalizeToReg(loOperand(Value));
2375 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr))); 2602 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr)));
2376 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); 2603 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr)));
2377 } else { 2604 } else {
2378 Variable *ValueR = legalizeToReg(Value); 2605 Variable *ValueR = legalizeToReg(Value);
2379 _sw(ValueR, NewAddr); 2606 _sw(ValueR, NewAddr);
2380 } 2607 }
2381 } 2608 }
2382 2609
2383 void TargetMIPS32::doAddressOptStore() { UnimplementedError(getFlags()); } 2610 void TargetMIPS32::doAddressOptStore() {
2611 Inst *Instr = iteratorToInst(Context.getCur());
2612 assert(llvm::isa<InstStore>(Instr));
2613 Operand *Src = Instr->getSrc(0);
2614 Operand *Addr = Instr->getSrc(1);
2615 if (OperandMIPS32Mem *Mem =
2616 formAddressingMode(Src->getType(), Func, Instr, Addr)) {
2617 Instr->setDeleted();
2618 Context.insert<InstStore>(Src, Mem);
2619 }
2620 }
2384 2621
2385 void TargetMIPS32::lowerSwitch(const InstSwitch *Instr) { 2622 void TargetMIPS32::lowerSwitch(const InstSwitch *Instr) {
2386 Operand *Src = Instr->getComparison(); 2623 Operand *Src = Instr->getComparison();
2387 SizeT NumCases = Instr->getNumCases(); 2624 SizeT NumCases = Instr->getNumCases();
2388 if (Src->getType() == IceType_i64) { 2625 if (Src->getType() == IceType_i64) {
2389 Src = legalizeUndef(Src); 2626 Src = legalizeUndef(Src);
2390 Variable *Src0Lo = legalizeToReg(loOperand(Src)); 2627 Variable *Src0Lo = legalizeToReg(loOperand(Src));
2391 Variable *Src0Hi = legalizeToReg(hiOperand(Src)); 2628 Variable *Src0Hi = legalizeToReg(hiOperand(Src));
2392 for (SizeT I = 0; I < NumCases; ++I) { 2629 for (SizeT I = 0; I < NumCases; ++I) {
2393 Operand *ValueLo = Ctx->getConstantInt32(Instr->getValue(I)); 2630 Operand *ValueLo = Ctx->getConstantInt32(Instr->getValue(I));
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 Str << "\t.set\t" 2966 Str << "\t.set\t"
2730 << "nomips16\n"; 2967 << "nomips16\n";
2731 } 2968 }
2732 2969
2733 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 2970 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
2734 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 2971 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
2735 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 2972 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
2736 2973
2737 } // end of namespace MIPS32 2974 } // end of namespace MIPS32
2738 } // end of namespace Ice 2975 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/mips-address-mode-opt.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698