forked from OSchip/llvm-project
				
			Add -arm-long-calls option to force calls to be indirect. This makes the
kernel linker happier when dealing with kexts. Radar 7805069 llvm-svn: 101303
This commit is contained in:
		
							parent
							
								
									20c87b1adf
								
							
						
					
					
						commit
						32bb362655
					
				| 
						 | 
					@ -40,12 +40,18 @@
 | 
				
			||||||
#include "llvm/MC/MCSectionMachO.h"
 | 
					#include "llvm/MC/MCSectionMachO.h"
 | 
				
			||||||
#include "llvm/Target/TargetOptions.h"
 | 
					#include "llvm/Target/TargetOptions.h"
 | 
				
			||||||
#include "llvm/ADT/VectorExtras.h"
 | 
					#include "llvm/ADT/VectorExtras.h"
 | 
				
			||||||
 | 
					#include "llvm/Support/CommandLine.h"
 | 
				
			||||||
#include "llvm/Support/ErrorHandling.h"
 | 
					#include "llvm/Support/ErrorHandling.h"
 | 
				
			||||||
#include "llvm/Support/MathExtras.h"
 | 
					#include "llvm/Support/MathExtras.h"
 | 
				
			||||||
#include "llvm/Support/raw_ostream.h"
 | 
					#include "llvm/Support/raw_ostream.h"
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
using namespace llvm;
 | 
					using namespace llvm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cl::opt<bool>
 | 
				
			||||||
 | 
					EnableARMLongCalls("arm-long-calls", cl::Hidden,
 | 
				
			||||||
 | 
					  cl::desc("Generate calls via indirect call instructions."),
 | 
				
			||||||
 | 
					  cl::init(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
 | 
					static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
 | 
				
			||||||
                                   CCValAssign::LocInfo &LocInfo,
 | 
					                                   CCValAssign::LocInfo &LocInfo,
 | 
				
			||||||
                                   ISD::ArgFlagsTy &ArgFlags,
 | 
					                                   ISD::ArgFlagsTy &ArgFlags,
 | 
				
			||||||
| 
						 | 
					@ -1027,7 +1033,43 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
 | 
				
			||||||
  bool isLocalARMFunc = false;
 | 
					  bool isLocalARMFunc = false;
 | 
				
			||||||
  MachineFunction &MF = DAG.getMachineFunction();
 | 
					  MachineFunction &MF = DAG.getMachineFunction();
 | 
				
			||||||
  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
 | 
					  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
 | 
				
			||||||
  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
 | 
					
 | 
				
			||||||
 | 
					  if (EnableARMLongCalls) {
 | 
				
			||||||
 | 
					    assert (getTargetMachine().getRelocationModel() == Reloc::Static
 | 
				
			||||||
 | 
					            && "long-calls with non-static relocation model!");
 | 
				
			||||||
 | 
					    // Handle a global address or an external symbol. If it's not one of
 | 
				
			||||||
 | 
					    // those, the target's already in a register, so we don't need to do
 | 
				
			||||||
 | 
					    // anything extra.
 | 
				
			||||||
 | 
					    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
 | 
				
			||||||
 | 
					      GlobalValue *GV = G->getGlobal();
 | 
				
			||||||
 | 
					      // Create a constant pool entry for the callee address
 | 
				
			||||||
 | 
					      unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
 | 
				
			||||||
 | 
					      ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV,
 | 
				
			||||||
 | 
					                                                           ARMPCLabelIndex,
 | 
				
			||||||
 | 
					                                                           ARMCP::CPValue, 0);
 | 
				
			||||||
 | 
					      // Get the address of the callee into a register
 | 
				
			||||||
 | 
					      SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
 | 
				
			||||||
 | 
					      CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
 | 
				
			||||||
 | 
					      Callee = DAG.getLoad(getPointerTy(), dl,
 | 
				
			||||||
 | 
					                           DAG.getEntryNode(), CPAddr,
 | 
				
			||||||
 | 
					                           PseudoSourceValue::getConstantPool(), 0,
 | 
				
			||||||
 | 
					                           false, false, 0);
 | 
				
			||||||
 | 
					    } else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
 | 
				
			||||||
 | 
					      const char *Sym = S->getSymbol();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Create a constant pool entry for the callee address
 | 
				
			||||||
 | 
					      unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
 | 
				
			||||||
 | 
					      ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(),
 | 
				
			||||||
 | 
					                                                       Sym, ARMPCLabelIndex, 0);
 | 
				
			||||||
 | 
					      // Get the address of the callee into a register
 | 
				
			||||||
 | 
					      SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
 | 
				
			||||||
 | 
					      CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
 | 
				
			||||||
 | 
					      Callee = DAG.getLoad(getPointerTy(), dl,
 | 
				
			||||||
 | 
					                           DAG.getEntryNode(), CPAddr,
 | 
				
			||||||
 | 
					                           PseudoSourceValue::getConstantPool(), 0,
 | 
				
			||||||
 | 
					                           false, false, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
 | 
				
			||||||
    GlobalValue *GV = G->getGlobal();
 | 
					    GlobalValue *GV = G->getGlobal();
 | 
				
			||||||
    isDirect = true;
 | 
					    isDirect = true;
 | 
				
			||||||
    bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
 | 
					    bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
 | 
				
			||||||
| 
						 | 
					@ -1051,7 +1093,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
 | 
				
			||||||
      SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
 | 
					      SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
 | 
				
			||||||
      Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
 | 
					      Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
 | 
				
			||||||
                           getPointerTy(), Callee, PICLabel);
 | 
					                           getPointerTy(), Callee, PICLabel);
 | 
				
			||||||
   } else
 | 
					    } else
 | 
				
			||||||
      Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
 | 
					      Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
 | 
				
			||||||
  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
 | 
					  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
 | 
				
			||||||
    isDirect = true;
 | 
					    isDirect = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue