llvm.org GIT mirror llvm / 9af7e9a
Move the check for "calls setjmp" to SelectionDAGISel so that it can be used by more than just the stack slot coloring algorithm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104722 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 10 years ago
3 changed file(s) with 50 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
113113 ///
114114 unsigned FunctionNumber;
115115
116 /// The alignment of the function.
116 /// Alignment - The alignment of the function.
117117 unsigned Alignment;
118
119 /// CallsSetJmp - True if the function calls setjmp or sigsetjmp. This is used
120 /// to limit optimizations which cannot reason about the control flow of
121 /// setjmp.
122 bool CallsSetJmp;
118123
119124 MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
120125 void operator=(const MachineFunction&); // DO NOT IMPLEMENT
179184 /// EnsureAlignment - Make sure the function is at least 'A' bits aligned.
180185 void EnsureAlignment(unsigned A) {
181186 if (Alignment < A) Alignment = A;
187 }
188
189 /// callsSetJmp - Returns true if the function calls setjmp or sigsetjmp.
190 bool callsSetJmp() const {
191 return CallsSetJmp;
192 }
193
194 /// setCallsSetJmp - Set a flag that indicates if there's a call to setjmp or
195 /// sigsetjmp.
196 void setCallsSetJmp(bool B) {
197 CallsSetJmp = B;
182198 }
183199
184200 /// getInfo - Keep track of various per-function pieces of information for
2424 #include "llvm/Intrinsics.h"
2525 #include "llvm/IntrinsicInst.h"
2626 #include "llvm/LLVMContext.h"
27 #include "llvm/Module.h"
2728 #include "llvm/CodeGen/FastISel.h"
2829 #include "llvm/CodeGen/GCStrategy.h"
2930 #include "llvm/CodeGen/GCMetadata.h"
190191 MachineFunctionPass::getAnalysisUsage(AU);
191192 }
192193
194 /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or
195 /// sigsetjmp. This is used to limit code-gen optimizations on the machine
196 /// function.
197 static bool FunctionCallsSetJmp(const Function *F) {
198 const Module *M = F->getParent();
199 const Function *SetJmp = M->getFunction("setjmp");
200 const Function *SigSetJmp = M->getFunction("sigsetjmp");
201
202 if (!SetJmp && !SigSetJmp)
203 return false;
204
205 if (SetJmp && !SetJmp->use_empty())
206 for (Value::const_use_iterator
207 I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I)
208 if (const CallInst *CI = dyn_cast(I))
209 if (CI->getParent()->getParent() == F)
210 return true;
211
212 if (SigSetJmp && !SigSetJmp->use_empty())
213 for (Value::const_use_iterator
214 I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I)
215 if (const CallInst *CI = dyn_cast(I))
216 if (CI->getParent()->getParent() == F)
217 return true;
218
219 return false;
220 }
221
193222 bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
194223 // Do some sanity-checking on the command-line options.
195224 assert((!EnableFastISelVerbose || EnableFastISel) &&
251280 }
252281 done:;
253282 }
283
284 // Determine if there is a call to setjmp in the machine function.
285 MF->setCallsSetJmp(FunctionCallsSetJmp(&Fn));
254286
255287 // Release function-specific state. SDB and CurDAG are already cleared
256288 // at this point.
159159 return LHS->weight > RHS->weight;
160160 }
161161 };
162 }
163
164 /// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in
165 /// this function.
166 bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) const {
167 const Function *F = MF.getFunction();
168 const Module *M = F->getParent();
169 const Function *SetJmp = M->getFunction("setjmp");
170 const Function *SigSetJmp = M->getFunction("sigsetjmp");
171
172 if (!SetJmp && !SigSetJmp)
173 return false;
174
175 if (SetJmp && !SetJmp->use_empty())
176 for (Value::const_use_iterator
177 I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I)
178 if (const CallInst *CI = dyn_cast(I))
179 if (CI->getParent()->getParent() == F)
180 return true;
181
182 if (SigSetJmp && !SigSetJmp->use_empty())
183 for (Value::const_use_iterator
184 I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I)
185 if (const CallInst *CI = dyn_cast(I))
186 if (CI->getParent()->getParent() == F)
187 return true;
188
189 return false;
190162 }
191163
192164 /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot
756728 // coloring. The stack could be modified before the longjmp is executed,
757729 // resulting in the wrong value being used afterwards. (See
758730 // .)
759 //
760 // FIXME: This goes beyond the setjmp/sigsetjmp functions. Ideally, we should
761 // check for the GCC "returns twice" attribute.
762 if (CheckForSetJmpCall(MF))
731 if (MF.callsSetJmp())
763732 return false;
764733
765734 // Gather spill slot references