Use indirect calls in PowerPC JIT.

See PR5201. There is no way to know if direct calls will be within the allowed
range for BL. Hence emit all calls as indirect when in JIT mode.
Without this long-running applications will fail to JIT on PowerPC with a
relocation failure.

llvm-svn: 110246
This commit is contained in:
Torok Edwin 2010-08-04 20:47:44 +00:00
parent ada023c5d6
commit 31e90d2dd1
3 changed files with 31 additions and 10 deletions

View File

@ -2467,18 +2467,31 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin; unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin;
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every bool needIndirectCall = true;
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG)) {
// node so that legalize doesn't hack it.
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,
Callee.getValueType());
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType());
else if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG))
// If this is an absolute destination address, use the munged value. // If this is an absolute destination address, use the munged value.
Callee = SDValue(Dest, 0); Callee = SDValue(Dest, 0);
else { needIndirectCall = false;
}
// XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201
// Use indirect calls for ALL functions calls in JIT mode, since the
// far-call stubs may be outside relocation limits for a BL instruction.
if (!DAG.getTarget().getSubtarget<PPCSubtarget>().isJITCodeModel()) {
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,
Callee.getValueType());
needIndirectCall = false;
}
}
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
Callee.getValueType());
needIndirectCall = false;
}
if (needIndirectCall) {
// Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair // Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair
// to do the call, we can't use PPCISD::CALL. // to do the call, we can't use PPCISD::CALL.
SDValue MTCTROps[] = {Chain, Callee, InFlag}; SDValue MTCTROps[] = {Chain, Callee, InFlag};

View File

@ -69,6 +69,7 @@ PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &FS,
, HasFSQRT(false) , HasFSQRT(false)
, HasSTFIWX(false) , HasSTFIWX(false)
, HasLazyResolverStubs(false) , HasLazyResolverStubs(false)
, IsJITCodeModel(false)
, DarwinVers(0) { , DarwinVers(0) {
// Determine default and user specified characteristics // Determine default and user specified characteristics
@ -117,6 +118,9 @@ void PPCSubtarget::SetJITMode() {
// everything is. This matters for PPC64, which codegens in PIC mode without // everything is. This matters for PPC64, which codegens in PIC mode without
// stubs. // stubs.
HasLazyResolverStubs = false; HasLazyResolverStubs = false;
// Calls to external functions need to use indirect calls
IsJITCodeModel = true;
} }

View File

@ -63,6 +63,7 @@ protected:
bool HasFSQRT; bool HasFSQRT;
bool HasSTFIWX; bool HasSTFIWX;
bool HasLazyResolverStubs; bool HasLazyResolverStubs;
bool IsJITCodeModel;
/// DarwinVers - Nonzero if this is a darwin platform. Otherwise, the numeric /// DarwinVers - Nonzero if this is a darwin platform. Otherwise, the numeric
/// version of the platform, e.g. 8 = 10.4 (Tiger), 9 = 10.5 (Leopard), etc. /// version of the platform, e.g. 8 = 10.4 (Tiger), 9 = 10.5 (Leopard), etc.
@ -124,6 +125,9 @@ public:
bool hasLazyResolverStub(const GlobalValue *GV, bool hasLazyResolverStub(const GlobalValue *GV,
const TargetMachine &TM) const; const TargetMachine &TM) const;
// isJITCodeModel - True if we're generating code for the JIT
bool isJITCodeModel() const { return IsJITCodeModel; }
// Specific obvious features. // Specific obvious features.
bool hasFSQRT() const { return HasFSQRT; } bool hasFSQRT() const { return HasFSQRT; }
bool hasSTFIWX() const { return HasSTFIWX; } bool hasSTFIWX() const { return HasSTFIWX; }