#define DEBUG_TYPE "codegenprepare"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/IRBuilder.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/DominatorInternals.h"
+#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Assembly/Writer.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/PatternMatch.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Utils/AddrModeMatcher.h"
}
bool runOnFunction(Function &F);
+ const char *getPassName() const { return "CodeGen Prepare"; }
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<DominatorTree>();
AU.addPreserved<ProfileInfo>();
TLInfo = &getAnalysis<TargetLibraryInfo>();
DT = getAnalysisIfAvailable<DominatorTree>();
PFI = getAnalysisIfAvailable<ProfileInfo>();
- OptSize = F.getFnAttributes().hasAttribute(Attributes::OptimizeForSize);
+ OptSize = F.getAttributes().hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::OptimizeForSize);
/// This optimization identifies DIV instructions that can be
/// profitably bypassed and carried out with a shorter, faster divide.
if (!DisableBranchOpts) {
MadeChange = false;
SmallPtrSet<BasicBlock*, 8> WorkList;
- SmallPtrSet<BasicBlock*, 8> LPadList;
- SmallVector<BasicBlock*, 8> ReturnList;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
- if (BB->isLandingPad()) LPadList.insert(BB);
- if (isa<ReturnInst>(BB->getTerminator())) ReturnList.push_back(BB);
MadeChange |= ConstantFoldTerminator(BB, true);
if (!MadeChange) continue;
}
// Delete the dead blocks and any of their dead successors.
- bool HadLPads = !LPadList.empty();
+ MadeChange |= !WorkList.empty();
while (!WorkList.empty()) {
BasicBlock *BB = *WorkList.begin();
WorkList.erase(BB);
- LPadList.erase(BB);
SmallVector<BasicBlock*, 2> Successors(succ_begin(BB), succ_end(BB));
DeleteDeadBlock(BB);
WorkList.insert(*II);
}
- if (HadLPads && LPadList.empty()) {
- // All of the landing pads were removed. Get rid of the SjLj EH context
- // code.
- Module *M = F.getParent();
-
- // These functions must exist if we have SjLj EH code to clean up.
- Constant *RegisterFn = M->getFunction("_Unwind_SjLj_Register");
- Constant *UnregisterFn = M->getFunction("_Unwind_SjLj_Unregister");
-
- if (RegisterFn) {
- Constant *LSDAAddrFn =
- Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_lsda);
- Constant *FrameAddrFn =
- Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
- Constant *StackAddrFn =
- Intrinsic::getDeclaration(M, Intrinsic::stacksave);
- Constant *BuiltinSetjmpFn =
- Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_setjmp);
- Constant *FuncCtxFn =
- Intrinsic::getDeclaration(M, Intrinsic::eh_sjlj_functioncontext);
-
- BasicBlock &Entry = F.getEntryBlock();
- SmallVector<Instruction*, 8> DeadInsts;
- for (BasicBlock::iterator I = Entry.begin(), E = Entry.end();
- I != E; ++I) {
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
- Value *Callee = CI->getCalledValue();
- bool IsDead = true;
- if (Callee != LSDAAddrFn && Callee != FrameAddrFn &&
- Callee != StackAddrFn && Callee != BuiltinSetjmpFn &&
- Callee != FuncCtxFn && Callee != RegisterFn)
- IsDead = false;
-
- if (IsDead) {
- Type *Ty = CI->getType();
- if (!Ty->isVoidTy())
- CI->replaceAllUsesWith(UndefValue::get(Ty));
- DeadInsts.push_back(CI);
- }
- }
- }
-
- // Find and remove the unregister calls.
- for (SmallVectorImpl<BasicBlock*>::iterator I = ReturnList.begin(),
- E = ReturnList.end(); I != E; ++I) {
- BasicBlock *BB = *I;
- typedef BasicBlock::InstListType::reverse_iterator reverse_iterator;
-
- for (reverse_iterator II = BB->getInstList().rbegin(),
- IE = BB->getInstList().rend(); II != IE; ++II) {
- if (CallInst *CI = dyn_cast<CallInst>(&*II)) {
- Value *Callee = CI->getCalledValue();
-
- if (Callee == UnregisterFn) {
- DeadInsts.push_back(CI);
- break;
- }
- }
- }
- }
-
- // Kill the dead instructions.
- for (SmallVectorImpl<Instruction*>::iterator I = DeadInsts.begin(),
- E = DeadInsts.end(); I != E; ++I)
- (*I)->eraseFromParent();
- }
- }
-
// Merge pairs of basic blocks with unconditional branches, connected by
// a single edge.
if (EverMadeChange || MadeChange)
// It's not safe to eliminate the sign / zero extension of the return value.
// See llvm::isInTailCallPosition().
const Function *F = BB->getParent();
- Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
- if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
- CallerRetAttr.hasAttribute(Attributes::SExt))
+ Attribute CallerRetAttr = F->getAttributes().getRetAttributes();
+ if (CallerRetAttr.hasAttribute(Attribute::ZExt) ||
+ CallerRetAttr.hasAttribute(Attribute::SExt))
return false;
// Make sure there are no instructions between the PHI and return, or that the
// Conservatively require the attributes of the call to match those of the
// return. Ignore noalias because it doesn't affect the call sequence.
- Attributes CalleeRetAttr = CS.getAttributes().getRetAttributes();
+ Attribute CalleeRetAttr = CS.getAttributes().getRetAttributes();
if (AttrBuilder(CalleeRetAttr).
- removeAttribute(Attributes::NoAlias) !=
+ removeAttribute(Attribute::NoAlias) !=
AttrBuilder(CallerRetAttr).
- removeAttribute(Attributes::NoAlias))
+ removeAttribute(Attribute::NoAlias))
continue;
// Make sure the call instruction is followed by an unconditional branch to