 Chromium Code Reviews
 Chromium Code Reviews Issue 27690005:
  [MIPS] Modify LongBranch expansion to work with sandboxing  (Closed) 
  Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
    
  
    Issue 27690005:
  [MIPS] Modify LongBranch expansion to work with sandboxing  (Closed) 
  Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master| OLD | NEW | 
|---|---|
| 1 //===-- MipsLongBranch.cpp - Emit long branches ---------------------------===// | 1 //===-- MipsLongBranch.cpp - Emit long branches ---------------------------===// | 
| 2 // | 2 // | 
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure | 
| 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 // This pass expands a branch or jump instruction into a long branch if its | 10 // This pass expands a branch or jump instruction into a long branch if its | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 | 61 | 
| 62 class MipsLongBranch : public MachineFunctionPass { | 62 class MipsLongBranch : public MachineFunctionPass { | 
| 63 | 63 | 
| 64 public: | 64 public: | 
| 65 static char ID; | 65 static char ID; | 
| 66 MipsLongBranch(TargetMachine &tm) | 66 MipsLongBranch(TargetMachine &tm) | 
| 67 : MachineFunctionPass(ID), TM(tm), | 67 : MachineFunctionPass(ID), TM(tm), | 
| 68 TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), | 68 TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), | 
| 69 IsPIC(TM.getRelocationModel() == Reloc::PIC_), | 69 IsPIC(TM.getRelocationModel() == Reloc::PIC_), | 
| 70 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), | 70 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), | 
| 71 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} | 71 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : | 
| 72 (/*@LOCALMOD*/Triple(TM.getTargetTriple()).isOSNaCl() ? 10 : 9))) {} | |
| 72 | 73 | 
| 73 virtual const char *getPassName() const { | 74 virtual const char *getPassName() const { | 
| 74 return "Mips Long Branch"; | 75 return "Mips Long Branch"; | 
| 75 } | 76 } | 
| 76 | 77 | 
| 77 bool runOnMachineFunction(MachineFunction &F); | 78 bool runOnMachineFunction(MachineFunction &F); | 
| 78 | 79 | 
| 79 private: | 80 private: | 
| 80 void splitMBB(MachineBasicBlock *MBB); | 81 void splitMBB(MachineBasicBlock *MBB); | 
| 81 void initMBBInfo(); | 82 void initMBBInfo(); | 
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 MBB->removeSuccessor(TgtMBB); | 257 MBB->removeSuccessor(TgtMBB); | 
| 257 MBB->addSuccessor(LongBrMBB); | 258 MBB->addSuccessor(LongBrMBB); | 
| 258 | 259 | 
| 259 if (IsPIC) { | 260 if (IsPIC) { | 
| 260 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); | 261 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); | 
| 261 MF->insert(FallThroughMBB, BalTgtMBB); | 262 MF->insert(FallThroughMBB, BalTgtMBB); | 
| 262 LongBrMBB->addSuccessor(BalTgtMBB); | 263 LongBrMBB->addSuccessor(BalTgtMBB); | 
| 263 BalTgtMBB->addSuccessor(TgtMBB); | 264 BalTgtMBB->addSuccessor(TgtMBB); | 
| 264 | 265 | 
| 265 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; | 266 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; | 
| 266 unsigned BalTgtMBBSize = 5; | 267 // @LOCALMOD-START | 
| 268 unsigned BalTgtMBBSize = Triple(TM.getTargetTriple()).isOSNaCl() ? 6 : 5; | |
| 269 // @LOCALMOD-END | |
| 267 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); | 270 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); | 
| 268 int64_t Lo = SignExtend64<16>(Offset & 0xffff); | 271 int64_t Lo = SignExtend64<16>(Offset & 0xffff); | 
| 269 int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); | 272 int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); | 
| 270 | 273 | 
| 271 if (ABI != MipsSubtarget::N64) { | 274 if (ABI != MipsSubtarget::N64) { | 
| 272 // $longbr: | 275 // $longbr: | 
| 273 // addiu $sp, $sp, -8 | 276 // addiu $sp, $sp, -8 | 
| 274 // sw $ra, 0($sp) | 277 // sw $ra, 0($sp) | 
| 275 // bal $baltgt | 278 // bal $baltgt | 
| 276 // lui $at, %hi($tgt - $baltgt) | 279 // lui $at, %hi($tgt - $baltgt) | 
| 277 // $baltgt: | 280 // $baltgt: | 
| 278 // addiu $at, $at, %lo($tgt - $baltgt) | 281 // addiu $at, $at, %lo($tgt - $baltgt) | 
| 279 // addu $at, $ra, $at | 282 // addu $at, $ra, $at | 
| 280 // lw $ra, 0($sp) | 283 // lw $ra, 0($sp) | 
| 281 // jr $at | 284 // jr $at | 
| 282 // addiu $sp, $sp, 8 | 285 // addiu $sp, $sp, 8 | 
| 283 // $fallthrough: | 286 // $fallthrough: | 
| 284 // | 287 // | 
| 285 | 288 | 
| 286 Pos = LongBrMBB->begin(); | 289 Pos = LongBrMBB->begin(); | 
| 287 | 290 | 
| 288 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | 291 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | 
| 289 .addReg(Mips::SP).addImm(-8); | 292 .addReg(Mips::SP).addImm(-8); | 
| 290 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) | 293 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) | 
| 291 .addReg(Mips::SP).addImm(0); | 294 .addReg(Mips::SP).addImm(0); | 
| 292 | 295 | 
| 293 MIBundleBuilder(*LongBrMBB, Pos) | 296 if (Triple(TM.getTargetTriple()).isOSNaCl()) { | 
| 294 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) | 297 // @LOCALMOD-START | 
| 295 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); | 298 // We cannot use immediate value in LUi and ADDiu instructions below | 
| 299 // which create 32-bit offset of the target basic block from the BAL | |
| 300 // target because it does not take sandboxed instructions into account | |
| 301 // (sanboxing is run after this pass). We therefore replace it with | |
| 
Mark Seaborn
2013/10/24 23:38:43
"sandboxing"
 
petarj
2013/11/21 18:23:42
Done.
 | |
| 302 // basic block operand which is resolved during fixup. | |
| 303 MIBundleBuilder(*LongBrMBB, Pos) | |
| 304 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) | |
| 305 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT) | |
| 306 .addMBB(TgtMBB, MipsII::MO_NACL_LONG_BRANCH_HI16)); | |
| 296 | 307 | 
| 297 Pos = BalTgtMBB->begin(); | 308 Pos = BalTgtMBB->begin(); | 
| 298 | 309 | 
| 299 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) | 310 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) | 
| 300 .addReg(Mips::AT).addImm(Lo); | 311 .addReg(Mips::AT).addMBB(TgtMBB, MipsII::MO_NACL_LONG_BRANCH_LO16); | 
| 301 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) | 312 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) | 
| 302 .addReg(Mips::RA).addReg(Mips::AT); | 313 .addReg(Mips::RA).addReg(Mips::AT); | 
| 303 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | 314 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | 
| 304 .addReg(Mips::SP).addImm(0); | 315 .addReg(Mips::SP).addImm(0); | 
| 305 | 316 | 
| 306 MIBundleBuilder(*BalTgtMBB, Pos) | 317 // In NaCl, modifying sp is not allowed in branch delay slot. | 
| 307 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | 318 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | 
| 308 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) | 319 .addReg(Mips::SP).addImm(8); | 
| 309 .addReg(Mips::SP).addImm(8)); | 320 | 
| 321 MIBundleBuilder(*BalTgtMBB, Pos) | |
| 322 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | |
| 323 .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); | |
| 324 | |
| 325 // Align target of JR instruction. | |
| 326 TgtMBB->setAlignment(4); | |
| 327 // @LOCALMOD-END | |
| 328 } else { | |
| 329 MIBundleBuilder(*LongBrMBB, Pos) | |
| 330 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) | |
| 331 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); | |
| 332 | |
| 333 Pos = BalTgtMBB->begin(); | |
| 334 | |
| 335 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) | |
| 336 .addReg(Mips::AT).addImm(Lo); | |
| 337 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) | |
| 338 .addReg(Mips::RA).addReg(Mips::AT); | |
| 339 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | |
| 340 .addReg(Mips::SP).addImm(0); | |
| 341 | |
| 342 MIBundleBuilder(*BalTgtMBB, Pos) | |
| 343 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | |
| 344 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) | |
| 345 .addReg(Mips::SP).addImm(8)); | |
| 346 } | |
| 310 } else { | 347 } else { | 
| 311 // $longbr: | 348 // $longbr: | 
| 312 // daddiu $sp, $sp, -16 | 349 // daddiu $sp, $sp, -16 | 
| 313 // sd $ra, 0($sp) | 350 // sd $ra, 0($sp) | 
| 314 // lui64 $at, %highest($tgt - $baltgt) | 351 // lui64 $at, %highest($tgt - $baltgt) | 
| 315 // daddiu $at, $at, %higher($tgt - $baltgt) | 352 // daddiu $at, $at, %higher($tgt - $baltgt) | 
| 316 // dsll $at, $at, 16 | 353 // dsll $at, $at, 16 | 
| 317 // daddiu $at, $at, %hi($tgt - $baltgt) | 354 // daddiu $at, $at, %hi($tgt - $baltgt) | 
| 318 // bal $baltgt | 355 // bal $baltgt | 
| 319 // dsll $at, $at, 16 | 356 // dsll $at, $at, 16 | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 while (MadeChange) { | 460 while (MadeChange) { | 
| 424 MadeChange = false; | 461 MadeChange = false; | 
| 425 | 462 | 
| 426 for (I = MBBInfos.begin(); I != E; ++I) { | 463 for (I = MBBInfos.begin(); I != E; ++I) { | 
| 427 // Skip if this MBB doesn't have a branch or the branch has already been | 464 // Skip if this MBB doesn't have a branch or the branch has already been | 
| 428 // converted to a long branch. | 465 // converted to a long branch. | 
| 429 if (!I->Br || I->HasLongBranch) | 466 if (!I->Br || I->HasLongBranch) | 
| 430 continue; | 467 continue; | 
| 431 | 468 | 
| 432 // Check if offset fits into 16-bit immediate field of branches. | 469 // Check if offset fits into 16-bit immediate field of branches. | 
| 433 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) | 470 if (Triple(TM.getTargetTriple()).isOSNaCl()) { | 
| 434 continue; | 471 // @LOCALMOD-START | 
| 472 int64_t Offset = computeOffset(I->Br) / 4; | |
| 473 | |
| 474 // This offset calculation does not include sandboxing instructions | |
| 475 // that will be added later. Since at this point we dont know the | |
| 
Mark Seaborn
2013/10/24 23:38:43
"don't".  Maybe "added later in the MC layer" (whi
 
petarj
2013/11/21 18:23:42
Done.
 | |
| 476 // exact amount of code that sanboxing will add, we conservatively | |
| 
Mark Seaborn
2013/10/24 23:38:43
"sandboxing"
 
petarj
2013/11/21 18:23:42
Done.
 | |
| 477 // estimate that code will not grow more than 100%. | |
| 478 Offset *= 2; | |
| 479 | |
| 480 if (!ForceLongBranch && isInt<16>(Offset)) | |
| 481 continue; | |
| 482 // @LOCALMOD-END | |
| 483 } else { | |
| 484 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) | |
| 485 continue; | |
| 486 } | |
| 435 | 487 | 
| 436 I->HasLongBranch = true; | 488 I->HasLongBranch = true; | 
| 437 I->Size += LongBranchSeqSize * 4; | 489 I->Size += LongBranchSeqSize * 4; | 
| 438 ++LongBranches; | 490 ++LongBranches; | 
| 439 EverMadeChange = MadeChange = true; | 491 EverMadeChange = MadeChange = true; | 
| 440 } | 492 } | 
| 441 } | 493 } | 
| 442 | 494 | 
| 443 if (!EverMadeChange) | 495 if (!EverMadeChange) | 
| 444 return true; | 496 return true; | 
| 445 | 497 | 
| 446 // Compute basic block addresses. | 498 // Compute basic block addresses. | 
| 447 if (TM.getRelocationModel() == Reloc::PIC_) { | 499 if (TM.getRelocationModel() == Reloc::PIC_) { | 
| 448 uint64_t Address = 0; | 500 uint64_t Address = 0; | 
| 449 | 501 | 
| 450 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) | 502 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) | 
| 451 I->Address = Address; | 503 I->Address = Address; | 
| 452 } | 504 } | 
| 453 | 505 | 
| 454 // Do the expansion. | 506 // Do the expansion. | 
| 455 for (I = MBBInfos.begin(); I != E; ++I) | 507 for (I = MBBInfos.begin(); I != E; ++I) | 
| 456 if (I->HasLongBranch) | 508 if (I->HasLongBranch) | 
| 457 expandToLongBranch(*I); | 509 expandToLongBranch(*I); | 
| 458 | 510 | 
| 459 MF->RenumberBlocks(); | 511 MF->RenumberBlocks(); | 
| 460 | 512 | 
| 461 return true; | 513 return true; | 
| 462 } | 514 } | 
| OLD | NEW |