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

Side by Side Diff: lib/Target/Mips/MipsLongBranch.cpp

Issue 27690005: [MIPS] Modify LongBranch expansion to work with sandboxing (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Changes per code review. Created 7 years, 1 month 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
OLDNEW
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
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
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 // LUi and ADDiu instructions create 32-bit offset of the target basic
299 // block from the BAL target. We cannot use immediate value as the
300 // offset (as non-NaCl version does) because it does not take
301 // sandboxed instructions into account ("sanboxing" is run after this
302 // pass). We therefore replace it with relocation expressions
303 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt). This expressions are
304 // resolved during the fixup after all sandboxing code is added, so the
305 // values will always be correct.
306 //
307 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt)
308 // expressions at this point (it is possible only at the MC layer),
309 // we replace LUi and ADDiu with pseudo instructions
310 // NACL_LONG_BRANCH_LUi and NACL_LONG_BRANCH_ADDiu, and add both basic
311 // block as operands to these instructions. When lowering these pseudo
312 // instructions to LUi and ADDiu in the MC layer, we will create
313 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions add add them as
314 // operands to lowered instructions.
315 MIBundleBuilder(*LongBrMBB, Pos)
316 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
317 .append(BuildMI(*MF, DL, TII->get(Mips::NACL_LONG_BRANCH_LUi),
318 Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB));
296 319
297 Pos = BalTgtMBB->begin(); 320 Pos = BalTgtMBB->begin();
298 321
299 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) 322 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NACL_LONG_BRANCH_ADDiu),
300 .addReg(Mips::AT).addImm(Lo); 323 Mips::AT).addReg(Mips::AT).addMBB(TgtMBB).addMBB(BalTgtMBB);
301 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) 324 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
302 .addReg(Mips::RA).addReg(Mips::AT); 325 .addReg(Mips::RA).addReg(Mips::AT);
303 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) 326 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
304 .addReg(Mips::SP).addImm(0); 327 .addReg(Mips::SP).addImm(0);
305 328
306 MIBundleBuilder(*BalTgtMBB, Pos) 329 // In NaCl, modifying sp is not allowed in branch delay slot.
307 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) 330 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
308 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) 331 .addReg(Mips::SP).addImm(8);
309 .addReg(Mips::SP).addImm(8)); 332
333 MIBundleBuilder(*BalTgtMBB, Pos)
334 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
335 .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
336
337 // Align target of JR instruction.
338 TgtMBB->setAlignment(4);
339 // @LOCALMOD-END
340 } else {
341 MIBundleBuilder(*LongBrMBB, Pos)
342 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
343 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi));
344
345 Pos = BalTgtMBB->begin();
346
347 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT)
348 .addReg(Mips::AT).addImm(Lo);
349 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
350 .addReg(Mips::RA).addReg(Mips::AT);
351 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
352 .addReg(Mips::SP).addImm(0);
353
354 MIBundleBuilder(*BalTgtMBB, Pos)
355 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
356 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP)
357 .addReg(Mips::SP).addImm(8));
358 }
310 } else { 359 } else {
311 // $longbr: 360 // $longbr:
312 // daddiu $sp, $sp, -16 361 // daddiu $sp, $sp, -16
313 // sd $ra, 0($sp) 362 // sd $ra, 0($sp)
314 // lui64 $at, %highest($tgt - $baltgt) 363 // lui64 $at, %highest($tgt - $baltgt)
315 // daddiu $at, $at, %higher($tgt - $baltgt) 364 // daddiu $at, $at, %higher($tgt - $baltgt)
316 // dsll $at, $at, 16 365 // dsll $at, $at, 16
317 // daddiu $at, $at, %hi($tgt - $baltgt) 366 // daddiu $at, $at, %hi($tgt - $baltgt)
318 // bal $baltgt 367 // bal $baltgt
319 // dsll $at, $at, 16 368 // dsll $at, $at, 16
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 while (MadeChange) { 472 while (MadeChange) {
424 MadeChange = false; 473 MadeChange = false;
425 474
426 for (I = MBBInfos.begin(); I != E; ++I) { 475 for (I = MBBInfos.begin(); I != E; ++I) {
427 // Skip if this MBB doesn't have a branch or the branch has already been 476 // Skip if this MBB doesn't have a branch or the branch has already been
428 // converted to a long branch. 477 // converted to a long branch.
429 if (!I->Br || I->HasLongBranch) 478 if (!I->Br || I->HasLongBranch)
430 continue; 479 continue;
431 480
432 // Check if offset fits into 16-bit immediate field of branches. 481 // Check if offset fits into 16-bit immediate field of branches.
433 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) 482 if (Triple(TM.getTargetTriple()).isOSNaCl()) {
434 continue; 483 // @LOCALMOD-START
484 int64_t Offset = computeOffset(I->Br) / 4;
485
486 // This offset calculation does not include sandboxing instructions
487 // that will be added later in the MC layer. Since at this point we
488 // don't know the exact amount of code that "sanboxing" will add, we
489 // conservatively estimate that code will not grow more than 100%.
490 Offset *= 2;
491
492 if (!ForceLongBranch && isInt<16>(Offset))
493 continue;
494 // @LOCALMOD-END
495 } else {
496 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4))
497 continue;
498 }
435 499
436 I->HasLongBranch = true; 500 I->HasLongBranch = true;
437 I->Size += LongBranchSeqSize * 4; 501 I->Size += LongBranchSeqSize * 4;
438 ++LongBranches; 502 ++LongBranches;
439 EverMadeChange = MadeChange = true; 503 EverMadeChange = MadeChange = true;
440 } 504 }
441 } 505 }
442 506
443 if (!EverMadeChange) 507 if (!EverMadeChange)
444 return true; 508 return true;
445 509
446 // Compute basic block addresses. 510 // Compute basic block addresses.
447 if (TM.getRelocationModel() == Reloc::PIC_) { 511 if (TM.getRelocationModel() == Reloc::PIC_) {
448 uint64_t Address = 0; 512 uint64_t Address = 0;
449 513
450 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) 514 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I)
451 I->Address = Address; 515 I->Address = Address;
452 } 516 }
453 517
454 // Do the expansion. 518 // Do the expansion.
455 for (I = MBBInfos.begin(); I != E; ++I) 519 for (I = MBBInfos.begin(); I != E; ++I)
456 if (I->HasLongBranch) 520 if (I->HasLongBranch)
457 expandToLongBranch(*I); 521 expandToLongBranch(*I);
458 522
459 MF->RenumberBlocks(); 523 MF->RenumberBlocks();
460 524
461 return true; 525 return true;
462 } 526 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698