================
@@ -1808,15 +1782,101 @@ bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr
&MI) const {
splitAdjDynAlloc(MI);
return true;
- case TargetOpcode::LOAD_STACK_GUARD:
- expandLoadStackGuard(&MI);
+ case SystemZ::MOVE_SG:
+ expandStackGuardPseudo(MI, SystemZ::MVC);
+ return true;
+
+ case SystemZ::COMPARE_SG:
+ expandStackGuardPseudo(MI, SystemZ::CLC);
return true;
default:
return false;
}
}
+namespace {
+Register scavengeAddrReg(MachineInstr &MI, MachineBasicBlock *MBB) {
+ // create fresh RegScavanger instance.
+ RegScavenger RS;
+ // initialize RegScavenger to correct location
+ RS.enterBasicBlockEnd(*MBB);
+ RS.backward(MI);
+
+ // Attempt to find a free register.
+ Register Scratch = RS.FindUnusedReg(&SystemZ::ADDR64BitRegClass);
+ // If not found, scavenge one, i.e. evict something to a stack spill slot.
+ if (!Scratch) {
+ Scratch =
+ RS.scavengeRegisterBackwards(SystemZ::ADDR64BitRegClass,
+ MI, // Scavenge back to this position.
+ true, // Scope must include MI.
+ 0,
+ true // Spills are allowed.
+ );
+ }
+ return Scratch;
+}
+
+// Check MI (which should be either MOVE_SG or COMPARE_SG)
+// to see if the early-clobber flag on the def reg was honored. If so,
+// return that register. If not, scavenge a new register and return that.
+// This is a workaround for https://github.com/llvm/llvm-project/issues/172511
+// and should be removed once that issue is resolved.
+Register chooseAddrReg(MachineInstr &MI, MachineBasicBlock *MBB) {
+ Register DefReg = MI.getOperand(0).getReg();
+ Register OpReg = MI.getOperand(1).getReg();
+ // if we can use DefReg, return it
+ if (DefReg != OpReg)
+ return DefReg;
+ // otherwise, scavenge
+ return scavengeAddrReg(MI, MBB);
+}
+} // namespace
+
+// Emit the stack guard address load, depending on guard type.
+// Return the register the stack guard address was loaded into.
+unsigned SystemZInstrInfo::emitLoadStackGuardAddress(MachineInstr &MI,
+ Register AddrReg) const {
+ MachineBasicBlock &MBB = *(MI.getParent());
+ const MachineFunction &MF = *(MBB.getParent());
+ const auto DL = MI.getDebugLoc();
+
+ const Module *M = MF.getFunction().getParent();
+ StringRef GuardType = M->getStackProtectorGuard();
+
+ if (GuardType.empty() || (GuardType == "tls")) {
+ // emit a load of the TLS stack guard's address
+ BuildMI(MBB, MI, DL, get(SystemZ::LOAD_TSGA), AddrReg);
+ // return the appropriate stack guard offset (40 in the tls case).
+ return 40;
+ }
+ if (GuardType == "global") {
+ // emit a load of the global stack guard's address
+ BuildMI(MBB, MI, DL, get(SystemZ::LOAD_GSGA), AddrReg);
+ // return the appropriate stack guard offset (0 in the global case).
+ return 0;
+ }
+
+ llvm_unreachable((Twine("Unknown stack protector type \"") + GuardType +
"\"")
+ .str()
+ .c_str());
+}
+
+void SystemZInstrInfo::expandStackGuardPseudo(MachineInstr &MI,
+ unsigned Opcode) const {
+ MachineBasicBlock *MBB = MI.getParent();
+ Register AddrReg = chooseAddrReg(MI, MBB);
+ unsigned Offset = emitLoadStackGuardAddress(MI, AddrReg);
----------------
uweigand wrote:
I think the above two function calls could be inlined here? The scavenger
code might still stay in a separate function as it will be deleted later on
anyway.
https://github.com/llvm/llvm-project/pull/169317
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits