summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-04-05 18:13:16 +0000
committerManman Ren <manman.ren@gmail.com>2016-04-05 18:13:16 +0000
commite221a870d3a19550b78d07cb80e0839399e6220d (patch)
tree255cfd20ec05574b24a9c25e97ec3828adf3a91b /llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
parent99d607b63e4ade30f6edaf4d94dfb0809f58a7eb (diff)
downloadbcm5719-llvm-e221a870d3a19550b78d07cb80e0839399e6220d.tar.gz
bcm5719-llvm-e221a870d3a19550b78d07cb80e0839399e6220d.zip
Swift Calling Convention: swifterror target-independent change.
At IR level, the swifterror argument is an input argument with type ErrorObject**. For targets that support swifterror, we want to optimize it to behave as an inout value with type ErrorObject*; it will be passed in a fixed physical register. The main idea is to track the virtual registers for each swifterror value. We define swifterror values as AllocaInsts with swifterror attribute or a function argument with swifterror attribute. In SelectionDAGISel.cpp, we set up swifterror values (SwiftErrorVals) before handling the basic blocks. When iterating over all basic blocks in RPO, before actually visiting the basic block, we call mergeIncomingSwiftErrors to merge incoming swifterror values when there are multiple predecessors or to simply propagate them. There, we create a virtual register for each swifterror value in the entry block. For predecessors that are not yet visited, we create virtual registers to hold the swifterror values at the end of the predecessor. The assignments are saved in SwiftErrorWorklist and will be materialized at the end of visiting the basic block. When visiting a load from a swifterror value, we copy from the current virtual register assignment. When visiting a store to a swifterror value, we create a virtual register to hold the swifterror value and update SwiftErrorMap to track the current virtual register assignment. Differential Revision: http://reviews.llvm.org/D18108 llvm-svn: 265433
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/FastISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index b89d6a0d332..25c4e963443 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1324,6 +1324,15 @@ bool FastISel::selectBitCast(const User *I) {
return true;
}
+// Return true if we should copy from swift error to the final vreg as specified
+// by SwiftErrorWorklist.
+static bool shouldCopySwiftErrorsToFinalVRegs(const TargetLowering &TLI,
+ FunctionLoweringInfo &FuncInfo) {
+ if (!TLI.supportSwiftError())
+ return false;
+ return FuncInfo.SwiftErrorWorklist.count(FuncInfo.MBB);
+}
+
// Remove local value instructions starting from the instruction after
// SavedLastLocalValue to the current function insert point.
void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)
@@ -1347,7 +1356,11 @@ bool FastISel::selectInstruction(const Instruction *I) {
MachineInstr *SavedLastLocalValue = getLastLocalValue();
// Just before the terminator instruction, insert instructions to
// feed PHI nodes in successor blocks.
- if (isa<TerminatorInst>(I))
+ if (isa<TerminatorInst>(I)) {
+ // If we need to materialize any vreg from worklist, we bail out of
+ // FastISel.
+ if (shouldCopySwiftErrorsToFinalVRegs(TLI, FuncInfo))
+ return false;
if (!handlePHINodesInSuccessorBlocks(I->getParent())) {
// PHI node handling may have generated local value instructions,
// even though it failed to handle all PHI nodes.
@@ -1356,6 +1369,7 @@ bool FastISel::selectInstruction(const Instruction *I) {
removeDeadLocalValueCode(SavedLastLocalValue);
return false;
}
+ }
// FastISel does not handle any operand bundles except OB_funclet.
if (ImmutableCallSite CS = ImmutableCallSite(I))
OpenPOWER on IntegriCloud