1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
Index: llvm-2.7/lib/ExecutionEngine/JIT/JIT.cpp
===================================================================
--- llvm-2.7.orig/lib/ExecutionEngine/JIT/JIT.cpp 2010-02-16 12:11:14.000000000 +0100
+++ llvm-2.7/lib/ExecutionEngine/JIT/JIT.cpp 2010-07-12 11:03:03.047811849 +0200
@@ -254,7 +254,12 @@
MutexGuard guard(Lock);
JITs.erase(jit);
}
- void *getPointerToNamedFunction(const char *Name) const {
+ bool empty() {
+ MutexGuard guard(Lock);
+ return JITs.empty();
+ }
+ void *getPointerToNamedFunction(const char *Name,
+ bool AbortOnFailure = true) const {
MutexGuard guard(Lock);
assert(JITs.size() != 0 && "No Jit registered");
//search function in every instance of JIT
@@ -266,7 +271,19 @@
}
// The function is not available : fallback on the first created (will
// search in symbol of the current program/library)
- return (*JITs.begin())->getPointerToNamedFunction(Name);
+ return (*JITs.begin())->getPointerToNamedFunction(Name, AbortOnFailure);
+ }
+ void *getPointerToGlobalIfAvailable(GlobalValue *V) const {
+ MutexGuard guard(Lock);
+ assert(JITs.size() != 0 && "No Jit registered");
+ //search function in every instance of JIT
+ for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(),
+ end = JITs.end();
+ Jit != end; ++Jit) {
+ if (void *Ptr = (*Jit)->getPointerToGlobalIfAvailable(V))
+ return Ptr;
+ }
+ return 0;
}
};
ManagedStatic<JitPool> AllJits;
@@ -282,6 +299,22 @@
}
}
+extern "C" {
+ // getPointerToNamedFunctionOrNull - same as the above, but returns
+ // NULL instead of aborting if the function cannot be found.
+ void *getPointerToNamedFunctionOrNull(const char *Name) {
+ return !AllJits->empty() ? AllJits->getPointerToNamedFunction(Name, false) : 0;
+ }
+}
+
+extern "C" {
+ // getPointerToGlobalIfAvailable - same as the above, but for global
+ // variables, and only for those that have been codegened already.
+ void *getPointerToGlobalIfAvailable(GlobalValue *V) {
+ return !AllJits->empty() ? AllJits->getPointerToGlobalIfAvailable(V) : 0;
+ }
+}
+
JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode)
: ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode),
Index: llvm-2.7/lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- llvm-2.7.orig/lib/Target/PowerPC/PPCISelLowering.cpp 2010-03-02 02:55:18.000000000 +0100
+++ llvm-2.7/lib/Target/PowerPC/PPCISelLowering.cpp 2010-07-12 11:03:03.047811849 +0200
@@ -2450,6 +2450,9 @@
InFlag = Chain.getValue(1);
}
+extern "C" void *getPointerToNamedFunctionOrNull(const char *Name);
+extern "C" void *getPointerToGlobalIfAvailable(GlobalValue *Value);
+
static
unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
SDValue &Chain, DebugLoc dl, int SPDiff, bool isTailCall,
@@ -2462,6 +2465,29 @@
unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin;
+ // XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201
+ // and http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=399
+ // for Shark.
+ //
+ // If the callee is an ExternalSymbol node, and the symbol can be
+ // resolved to a function pointer, then insert that pointer as a
+ // constant. This causes the next block of code to fall into the
+ // block that emits an indirect call. This works around
+ //
+ // This works for Shark because the only kinds of call that Shark
+ // makes that do not already fall into the indirect call block are
+ // calls to pre-existing external functions.
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ void *FuncPtr = getPointerToNamedFunctionOrNull(S->getSymbol());
+ if (FuncPtr)
+ Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
+ }
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ void *FuncPtr = getPointerToGlobalIfAvailable(G->getGlobal());
+ if (FuncPtr)
+ Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
+ }
+
// 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.
Index: llvm-2.7/lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- llvm-2.7.orig/lib/Target/ARM/ARMISelLowering.cpp 2010-03-02 02:55:18.000000000 +0100
+++ llvm-2.7/lib/Target/ARM/ARMISelLowering.cpp 2010-07-12 11:03:03.057827385 +0200
@@ -895,6 +895,9 @@
}
}
+extern "C" void *getPointerToNamedFunctionOrNull(const char *Name);
+extern "C" void *getPointerToGlobalIfAvailable(GlobalValue *Value);
+
/// LowerCall - Lowering a call into a callseq_start <-
/// ARMISD:CALL <- callseq_end chain. Also add input and output parameter
/// nodes.
@@ -1004,6 +1007,31 @@
InFlag = Chain.getValue(1);
}
+ EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+
+ // XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201
+ // and http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=399
+ // for Shark.
+ //
+ // If the callee is an ExternalSymbol node, and the symbol can be
+ // resolved to a function pointer, then insert that pointer as a
+ // constant. This causes the next block of code to fall into the
+ // block that emits an indirect call. This works around
+ //
+ // This works for Shark because the only kinds of call that Shark
+ // makes that do not already fall into the indirect call block are
+ // calls to pre-existing external functions.
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ void *FuncPtr = getPointerToNamedFunctionOrNull(S->getSymbol());
+ if (FuncPtr)
+ Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
+ }
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ void *FuncPtr = getPointerToGlobalIfAvailable(G->getGlobal());
+ if (FuncPtr)
+ Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
+ }
+
// 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.
Index: llvm-2.7/tools/llc/CMakeLists.txt
===================================================================
--- llvm-2.7.orig/tools/llc/CMakeLists.txt 2009-09-03 00:45:31.000000000 +0200
+++ llvm-2.7/tools/llc/CMakeLists.txt 2010-07-12 11:03:03.057827385 +0200
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} jit bitreader asmparser)
add_llvm_tool(llc
llc.cpp
Index: llvm-2.7/tools/llvm-mc/CMakeLists.txt
===================================================================
--- llvm-2.7.orig/tools/llvm-mc/CMakeLists.txt 2010-07-12 11:07:09.417811782 +0200
+++ llvm-2.7/tools/llvm-mc/CMakeLists.txt 2010-07-12 11:07:19.866561599 +0200
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} jit support MC MCParser)
add_llvm_tool(llvm-mc
llvm-mc.cpp
|