[X86] enable PIE for functions

Call locally defined function directly for PIE/fPIE

Differential Revision: http://reviews.llvm.org/D19226

llvm-svn: 266863
diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp
index 5930e03..c8af972 100644
--- a/llvm/lib/Target/X86/X86Subtarget.cpp
+++ b/llvm/lib/Target/X86/X86Subtarget.cpp
@@ -144,6 +144,35 @@
   return X86II::MO_NO_FLAG;
 }
 
+unsigned char X86Subtarget::classifyGlobalFunctionReference(
+    const GlobalValue *GV, const TargetMachine &TM) const {
+  // On ELF targets, in both X86-64 and X86-32 mode, direct calls to
+  // external symbols most go through the PLT in PIC mode.  If the symbol
+  // has hidden or protected visibility, or if it is static or local, then
+  // we don't need to use the PLT - we can directly call it.
+  // In PIE mode, calls to global functions don't need to go through PLT
+  if (isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ &&
+      (!TM.Options.PositionIndependentExecutable ||
+       GV->isDeclarationForLinker()) &&
+      GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) {
+    return X86II::MO_PLT;
+  } else if (isPICStyleStubAny() && !GV->isStrongDefinitionForLinker() &&
+             (!getTargetTriple().isMacOSX() ||
+              getTargetTriple().isMacOSXVersionLT(10, 5))) {
+    // PC-relative references to external symbols should go through $stub,
+    // unless we're building with the leopard linker or later, which
+    // automatically synthesizes these stubs.
+    return X86II::MO_DARWIN_STUB;
+  } else if (isPICStyleRIPRel() && isa<Function>(GV) &&
+             cast<Function>(GV)->hasFnAttribute(Attribute::NonLazyBind)) {
+    // If the function is marked as non-lazy, generate an indirect call
+    // which loads from the GOT directly. This avoids runtime overhead
+    // at the cost of eager binding (and one extra byte of encoding).
+    return X86II::MO_GOTPCREL;
+  }
+
+  return X86II::MO_NO_FLAG;
+}
 
 /// This function returns the name of a function which has an interface like
 /// the non-standard bzero function, if such a function exists on the