aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorasl <asl@91177308-0d34-0410-b5e6-96231b3b80d8>2009-05-04 19:10:38 +0000
committerasl <asl@91177308-0d34-0410-b5e6-96231b3b80d8>2009-05-04 19:10:38 +0000
commit7a969d8c47d8916099ff7a2dcb87cf42137e03c4 (patch)
tree794cb788091fbdd3fcf7fae97e539163b620d1f0 /lib
parent025ddd416fefc58576422f092fcb1f6a30c6a632 (diff)
downloadexternal_llvm-7a969d8c47d8916099ff7a2dcb87cf42137e03c4.zip
external_llvm-7a969d8c47d8916099ff7a2dcb87cf42137e03c4.tar.gz
external_llvm-7a969d8c47d8916099ff7a2dcb87cf42137e03c4.tar.bz2
Fix code emission for conditional branches.
Patch by Collin Winter! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/CaptureTracking.cpp75
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp11
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp10
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp5
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp4
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp2
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp4
-rw-r--r--lib/VMCore/Value.cpp6
8 files changed, 64 insertions, 53 deletions
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp
index ceb9646..773f53d 100644
--- a/lib/Analysis/CaptureTracking.cpp
+++ b/lib/Analysis/CaptureTracking.cpp
@@ -49,11 +49,7 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
switch (I->getOpcode()) {
case Instruction::Call:
case Instruction::Invoke: {
- CallSite CS = CallSite::get(I);
- // Not captured if the callee is readonly and doesn't return a copy
- // through its return value.
- if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
- break;
+ CallSite CS(I);
// Not captured if only passed via 'nocapture' arguments. Note that
// calling a function pointer does not in itself cause the pointer to
@@ -62,46 +58,69 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
// that loading a value from a pointer does not cause the pointer to be
// captured, even though the loaded value might be the pointer itself
// (think of self-referential objects).
+ bool MayBeCaptured = false;
CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
for (CallSite::arg_iterator A = B; A != E; ++A)
- if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture))
- // The parameter is not marked 'nocapture' - captured.
- return true;
- // Only passed via 'nocapture' arguments, or is the called function - not
- // captured.
+ if (A->get() == V && !CS.paramHasAttr(A-B+1, Attribute::NoCapture)) {
+ // The parameter is not marked 'nocapture' - handled by generic code
+ // below.
+ MayBeCaptured = true;
+ break;
+ }
+ if (!MayBeCaptured)
+ // Only passed via 'nocapture' arguments, or is the called function -
+ // not captured.
+ continue;
+ if (!CS.doesNotThrow())
+ // Even a readonly function can leak bits by throwing an exception or
+ // not depending on the input value.
+ return true;
+ // Fall through to the generic code.
break;
}
case Instruction::Free:
// Freeing a pointer does not cause it to be captured.
- break;
+ continue;
case Instruction::Load:
// Loading from a pointer does not cause it to be captured.
- break;
+ continue;
case Instruction::Ret:
if (ReturnCaptures)
return true;
- break;
+ continue;
case Instruction::Store:
if (V == I->getOperand(0))
// Stored the pointer - it may be captured.
return true;
// Storing to the pointee does not cause the pointer to be captured.
- break;
- case Instruction::BitCast:
- case Instruction::GetElementPtr:
- case Instruction::PHI:
- case Instruction::Select:
- // The original value is not captured via this if the new value isn't.
- for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end();
- UI != UE; ++UI) {
- Use *U = &UI.getUse();
- if (Visited.insert(U))
- Worklist.push_back(U);
- }
- break;
- default:
- // Something else - be conservative and say it is captured.
+ continue;
+ }
+
+ // If it may write to memory and isn't one of the special cases above,
+ // be conservative and assume the pointer is captured.
+ if (I->mayWriteToMemory())
return true;
+
+ // If the instruction doesn't write memory, it can only capture by
+ // having its own value depend on the input value.
+ const Type* Ty = I->getType();
+ if (Ty == Type::VoidTy)
+ // The value of an instruction can't be a copy if it can't contain any
+ // information.
+ continue;
+ if (!isa<PointerType>(Ty))
+ // At the moment, we don't track non-pointer values, so be conservative
+ // and assume the pointer is captured.
+ // FIXME: Track these too. This would need to be done very carefully as
+ // it is easy to leak bits via control flow if integer values are allowed.
+ return true;
+
+ // The original value is not captured via this if the new value isn't.
+ for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end();
+ UI != UE; ++UI) {
+ Use *U = &UI.getUse();
+ if (Visited.insert(U))
+ Worklist.push_back(U);
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 848f45e..8ca8590 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -3262,11 +3262,12 @@ public:
// Assumes in correct section after the entry point.
EmitLabel("func_begin", ++SubprogramCount);
- // Emit label for the implicitly defined dbg.stoppoint at the start of
- // the function.
- if (!Lines.empty()) {
- const SrcLineInfo &LineInfo = Lines[0];
- Asm->printLabel(LineInfo.getLabelID());
+ DebugLoc FDL = MF->getDefaultDebugLoc();
+ if (!FDL.isUnknown()) {
+ DebugLocTuple DLT = MF->getDebugLocTuple(FDL);
+ unsigned LabelID = RecordSourceLine(DLT.Line, DLT.Col,
+ DICompileUnit(DLT.CompileUnit));
+ Asm->printLabel(LabelID);
}
if (TimePassesIsEnabled)
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index afcda1f..f710051 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -333,11 +333,6 @@ bool FastISel::SelectCall(User *I) {
unsigned Col = SPI->getColumn();
unsigned Idx = MF.getOrCreateDebugLocID(CU.getGV(), Line, Col);
setCurDebugLoc(DebugLoc::get(Idx));
- if (DW && DW->ShouldEmitDwarfDebug()) {
- unsigned ID = DW->RecordSourceLine(Line, Col, CU);
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, DL, II).addImm(ID);
- }
}
return true;
}
@@ -402,7 +397,7 @@ bool FastISel::SelectCall(User *I) {
CompileUnit.getGV(), Line, 0)));
if (DW && DW->ShouldEmitDwarfDebug()) {
- unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit);
+ unsigned LabelID = MMI->NextLabelID();
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
BuildMI(MBB, DL, II).addImm(LabelID);
DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
@@ -414,10 +409,9 @@ bool FastISel::SelectCall(User *I) {
} else {
// Record the source line.
unsigned Line = Subprogram.getLineNumber();
- setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
+ MF.setDefaultDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
CompileUnit.getGV(), Line, 0)));
if (DW && DW->ShouldEmitDwarfDebug()) {
- DW->RecordSourceLine(Line, 0, CompileUnit);
// llvm.dbg.func_start also defines beginning of function scope.
DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index acdb043..fc45bbd 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -3980,7 +3980,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
if (DW && DW->ShouldEmitDwarfDebug()) {
- unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit);
+ unsigned LabelID = DAG.getMachineModuleInfo()->NextLabelID();
DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
getRoot(), LabelID));
DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
@@ -3992,10 +3992,9 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
} else {
// Record the source line.
unsigned Line = Subprogram.getLineNumber();
- setCurDebugLoc(DebugLoc::get(
+ MF.setDefaultDebugLoc(DebugLoc::get(
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
if (DW && DW->ShouldEmitDwarfDebug()) {
- DW->RecordSourceLine(Line, 0, CompileUnit);
// llvm.dbg.func_start also defines beginning of function scope.
DW->RecordRegionStart(cast<GlobalVariable>(FSI.getSubprogram()));
}
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 6adb73a..bf9c885 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -1092,9 +1092,9 @@ namespace {
const BranchInst* br = cast<BranchInst>(I);
Out << "BranchInst::Create(" ;
if (br->getNumOperands() == 3 ) {
- Out << opNames[0] << ", "
+ Out << opNames[2] << ", "
<< opNames[1] << ", "
- << opNames[2] << ", ";
+ << opNames[0] << ", ";
} else if (br->getNumOperands() == 1) {
Out << opNames[0] << ", ";
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 32e1f7a..bf49ec0 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -28,8 +28,6 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include <queue>
-#include <set>
using namespace llvm;
/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 1844957..c0ca2df 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -120,8 +120,8 @@ bool JumpThreading::runOnFunction(Function &F) {
BB != &BB->getParent()->getEntryBlock()) {
DOUT << " JT: Deleting dead block '" << BB->getNameStart()
<< "' with terminator: " << *BB->getTerminator();
- DeleteDeadBlock(BB);
LoopHeaders.erase(BB);
+ DeleteDeadBlock(BB);
Changed = true;
}
}
@@ -133,7 +133,7 @@ bool JumpThreading::runOnFunction(Function &F) {
return EverChanged;
}
-/// FindLoopHeaders - We do not wan jump threading to turn proper loop
+/// FindLoopHeaders - We do not want jump threading to turn proper loop
/// structures into irreducible loops. Doing this breaks up the loop nesting
/// hierarchy and pessimizes later transformations. To prevent this from
/// happening, we first have to find the loop headers. Here we approximate this
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 35c8ccf..3af161f 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -406,8 +406,8 @@ Value *Value::DoPHITranslation(const BasicBlock *CurBB,
typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy;
static ManagedStatic<ValueHandlesTy> ValueHandles;
-/// AddToUseList - Add this ValueHandle to the use list for VP, where List is
-/// known to point into the existing use list.
+/// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
+/// List is known to point into the existing use list.
void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) {
assert(List && "Handle list is null?");
@@ -443,7 +443,7 @@ void ValueHandleBase::AddToUseList() {
ValueHandleBase *&Entry = Handles[VP];
assert(Entry == 0 && "Value really did already have handles?");
AddToExistingUseList(&Entry);
- VP->HasValueHandle = 1;
+ VP->HasValueHandle = true;
// If reallocation didn't happen or if this was the first insertion, don't
// walk the table.