forked from OSchip/llvm-project
Bit-pack some pairs. No functionlity change intended.
This commit is contained in:
parent
cca545ce46
commit
9a08c30705
|
@ -413,31 +413,33 @@ void WebAssemblyFixIrreducibleControlFlow::makeSingleEntryLoop(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record if each entry has a layout predecessor. This map stores
|
// Record if each entry has a layout predecessor. This map stores
|
||||||
// <<Predecessor is within the loop?, loop entry>, layout predecessor>
|
// <<loop entry, Predecessor is within the loop?>, layout predecessor>
|
||||||
std::map<std::pair<bool, MachineBasicBlock *>, MachineBasicBlock *>
|
DenseMap<PointerIntPair<MachineBasicBlock *, 1, bool>, MachineBasicBlock *>
|
||||||
EntryToLayoutPred;
|
EntryToLayoutPred;
|
||||||
for (auto *Pred : AllPreds)
|
for (auto *Pred : AllPreds) {
|
||||||
|
bool PredInLoop = InLoop.count(Pred);
|
||||||
for (auto *Entry : Pred->successors())
|
for (auto *Entry : Pred->successors())
|
||||||
if (Entries.count(Entry) && Pred->isLayoutSuccessor(Entry))
|
if (Entries.count(Entry) && Pred->isLayoutSuccessor(Entry))
|
||||||
EntryToLayoutPred[std::make_pair(InLoop.count(Pred), Entry)] = Pred;
|
EntryToLayoutPred[{Entry, PredInLoop}] = Pred;
|
||||||
|
}
|
||||||
|
|
||||||
// We need to create at most two routing blocks per entry: one for
|
// We need to create at most two routing blocks per entry: one for
|
||||||
// predecessors outside the loop and one for predecessors inside the loop.
|
// predecessors outside the loop and one for predecessors inside the loop.
|
||||||
// This map stores
|
// This map stores
|
||||||
// <<Predecessor is within the loop?, loop entry>, routing block>
|
// <<loop entry, Predecessor is within the loop?>, routing block>
|
||||||
std::map<std::pair<bool, MachineBasicBlock *>, MachineBasicBlock *> Map;
|
DenseMap<PointerIntPair<MachineBasicBlock *, 1, bool>, MachineBasicBlock *>
|
||||||
|
Map;
|
||||||
for (auto *Pred : AllPreds) {
|
for (auto *Pred : AllPreds) {
|
||||||
bool PredInLoop = InLoop.count(Pred);
|
bool PredInLoop = InLoop.count(Pred);
|
||||||
for (auto *Entry : Pred->successors()) {
|
for (auto *Entry : Pred->successors()) {
|
||||||
if (!Entries.count(Entry) ||
|
if (!Entries.count(Entry) || Map.count({Entry, PredInLoop}))
|
||||||
Map.count(std::make_pair(InLoop.count(Pred), Entry)))
|
|
||||||
continue;
|
continue;
|
||||||
// If there exists a layout predecessor of this entry and this predecessor
|
// If there exists a layout predecessor of this entry and this predecessor
|
||||||
// is not that, we rather create a routing block after that layout
|
// is not that, we rather create a routing block after that layout
|
||||||
// predecessor to save a branch.
|
// predecessor to save a branch.
|
||||||
if (EntryToLayoutPred.count(std::make_pair(PredInLoop, Entry)) &&
|
if (auto *OtherPred = EntryToLayoutPred.lookup({Entry, PredInLoop}))
|
||||||
EntryToLayoutPred[std::make_pair(PredInLoop, Entry)] != Pred)
|
if (OtherPred != Pred)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// This is a successor we need to rewrite.
|
// This is a successor we need to rewrite.
|
||||||
MachineBasicBlock *Routing = MF.CreateMachineBasicBlock();
|
MachineBasicBlock *Routing = MF.CreateMachineBasicBlock();
|
||||||
|
@ -453,7 +455,7 @@ void WebAssemblyFixIrreducibleControlFlow::makeSingleEntryLoop(
|
||||||
.addImm(Indices[Entry]);
|
.addImm(Indices[Entry]);
|
||||||
BuildMI(Routing, DebugLoc(), TII.get(WebAssembly::BR)).addMBB(Dispatch);
|
BuildMI(Routing, DebugLoc(), TII.get(WebAssembly::BR)).addMBB(Dispatch);
|
||||||
Routing->addSuccessor(Dispatch);
|
Routing->addSuccessor(Dispatch);
|
||||||
Map[std::make_pair(PredInLoop, Entry)] = Routing;
|
Map[{Entry, PredInLoop}] = Routing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,12 +465,12 @@ void WebAssemblyFixIrreducibleControlFlow::makeSingleEntryLoop(
|
||||||
for (MachineInstr &Term : Pred->terminators())
|
for (MachineInstr &Term : Pred->terminators())
|
||||||
for (auto &Op : Term.explicit_uses())
|
for (auto &Op : Term.explicit_uses())
|
||||||
if (Op.isMBB() && Indices.count(Op.getMBB()))
|
if (Op.isMBB() && Indices.count(Op.getMBB()))
|
||||||
Op.setMBB(Map[std::make_pair(PredInLoop, Op.getMBB())]);
|
Op.setMBB(Map[{Op.getMBB(), PredInLoop}]);
|
||||||
|
|
||||||
for (auto *Succ : Pred->successors()) {
|
for (auto *Succ : Pred->successors()) {
|
||||||
if (!Entries.count(Succ))
|
if (!Entries.count(Succ))
|
||||||
continue;
|
continue;
|
||||||
auto *Routing = Map[std::make_pair(PredInLoop, Succ)];
|
auto *Routing = Map[{Succ, PredInLoop}];
|
||||||
Pred->replaceSuccessor(Succ, Routing);
|
Pred->replaceSuccessor(Succ, Routing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ static bool PropagateConstantsIntoArguments(Function &F) {
|
||||||
|
|
||||||
// For each argument, keep track of its constant value and whether it is a
|
// For each argument, keep track of its constant value and whether it is a
|
||||||
// constant or not. The bool is driven to true when found to be non-constant.
|
// constant or not. The bool is driven to true when found to be non-constant.
|
||||||
SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants;
|
SmallVector<PointerIntPair<Constant *, 1, bool>, 16> ArgumentConstants;
|
||||||
ArgumentConstants.resize(F.arg_size());
|
ArgumentConstants.resize(F.arg_size());
|
||||||
|
|
||||||
unsigned NumNonconstant = 0;
|
unsigned NumNonconstant = 0;
|
||||||
|
@ -80,7 +80,7 @@ static bool PropagateConstantsIntoArguments(Function &F) {
|
||||||
for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++Arg) {
|
for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++Arg) {
|
||||||
|
|
||||||
// If this argument is known non-constant, ignore it.
|
// If this argument is known non-constant, ignore it.
|
||||||
if (ArgumentConstants[i].second)
|
if (ArgumentConstants[i].getInt())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value *V = ACS.getCallArgOperand(i);
|
Value *V = ACS.getCallArgOperand(i);
|
||||||
|
@ -102,13 +102,13 @@ static bool PropagateConstantsIntoArguments(Function &F) {
|
||||||
if (++NumNonconstant == ArgumentConstants.size())
|
if (++NumNonconstant == ArgumentConstants.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ArgumentConstants[i].second = true;
|
ArgumentConstants[i].setInt(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C && ArgumentConstants[i].first == nullptr) {
|
if (C && ArgumentConstants[i].getPointer() == nullptr) {
|
||||||
ArgumentConstants[i].first = C; // First constant seen.
|
ArgumentConstants[i].setPointer(C); // First constant seen.
|
||||||
} else if (C && ArgumentConstants[i].first == C) {
|
} else if (C && ArgumentConstants[i].getPointer() == C) {
|
||||||
// Still the constant value we think it is.
|
// Still the constant value we think it is.
|
||||||
} else if (V == &*Arg) {
|
} else if (V == &*Arg) {
|
||||||
// Ignore recursive calls passing argument down.
|
// Ignore recursive calls passing argument down.
|
||||||
|
@ -117,7 +117,7 @@ static bool PropagateConstantsIntoArguments(Function &F) {
|
||||||
// give up on this function.
|
// give up on this function.
|
||||||
if (++NumNonconstant == ArgumentConstants.size())
|
if (++NumNonconstant == ArgumentConstants.size())
|
||||||
return false;
|
return false;
|
||||||
ArgumentConstants[i].second = true;
|
ArgumentConstants[i].setInt(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,11 +128,11 @@ static bool PropagateConstantsIntoArguments(Function &F) {
|
||||||
Function::arg_iterator AI = F.arg_begin();
|
Function::arg_iterator AI = F.arg_begin();
|
||||||
for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
|
for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
|
||||||
// Do we have a constant argument?
|
// Do we have a constant argument?
|
||||||
if (ArgumentConstants[i].second || AI->use_empty() ||
|
if (ArgumentConstants[i].getInt() || AI->use_empty() ||
|
||||||
AI->hasInAllocaAttr() || (AI->hasByValAttr() && !F.onlyReadsMemory()))
|
AI->hasInAllocaAttr() || (AI->hasByValAttr() && !F.onlyReadsMemory()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value *V = ArgumentConstants[i].first;
|
Value *V = ArgumentConstants[i].getPointer();
|
||||||
if (!V) V = UndefValue::get(AI->getType());
|
if (!V) V = UndefValue::get(AI->getType());
|
||||||
AI->replaceAllUsesWith(V);
|
AI->replaceAllUsesWith(V);
|
||||||
++NumArgumentsProped;
|
++NumArgumentsProped;
|
||||||
|
|
|
@ -138,6 +138,7 @@ static const unsigned UninitializedAddressSpace =
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ValueToAddrSpaceMapTy = DenseMap<const Value *, unsigned>;
|
using ValueToAddrSpaceMapTy = DenseMap<const Value *, unsigned>;
|
||||||
|
using PostorderStackTy = llvm::SmallVector<PointerIntPair<Value *, 1, bool>, 4>;
|
||||||
|
|
||||||
/// InferAddressSpaces
|
/// InferAddressSpaces
|
||||||
class InferAddressSpaces : public FunctionPass {
|
class InferAddressSpaces : public FunctionPass {
|
||||||
|
@ -182,15 +183,14 @@ private:
|
||||||
const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const;
|
const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const;
|
||||||
|
|
||||||
void appendsFlatAddressExpressionToPostorderStack(
|
void appendsFlatAddressExpressionToPostorderStack(
|
||||||
Value *V, std::vector<std::pair<Value *, bool>> &PostorderStack,
|
Value *V, PostorderStackTy &PostorderStack,
|
||||||
DenseSet<Value *> &Visited) const;
|
DenseSet<Value *> &Visited) const;
|
||||||
|
|
||||||
bool rewriteIntrinsicOperands(IntrinsicInst *II,
|
bool rewriteIntrinsicOperands(IntrinsicInst *II,
|
||||||
Value *OldV, Value *NewV) const;
|
Value *OldV, Value *NewV) const;
|
||||||
void collectRewritableIntrinsicOperands(
|
void collectRewritableIntrinsicOperands(IntrinsicInst *II,
|
||||||
IntrinsicInst *II,
|
PostorderStackTy &PostorderStack,
|
||||||
std::vector<std::pair<Value *, bool>> &PostorderStack,
|
DenseSet<Value *> &Visited) const;
|
||||||
DenseSet<Value *> &Visited) const;
|
|
||||||
|
|
||||||
std::vector<WeakTrackingVH> collectFlatAddressExpressions(Function &F) const;
|
std::vector<WeakTrackingVH> collectFlatAddressExpressions(Function &F) const;
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ bool InferAddressSpaces::rewriteIntrinsicOperands(IntrinsicInst *II,
|
||||||
}
|
}
|
||||||
|
|
||||||
void InferAddressSpaces::collectRewritableIntrinsicOperands(
|
void InferAddressSpaces::collectRewritableIntrinsicOperands(
|
||||||
IntrinsicInst *II, std::vector<std::pair<Value *, bool>> &PostorderStack,
|
IntrinsicInst *II, PostorderStackTy &PostorderStack,
|
||||||
DenseSet<Value *> &Visited) const {
|
DenseSet<Value *> &Visited) const {
|
||||||
auto IID = II->getIntrinsicID();
|
auto IID = II->getIntrinsicID();
|
||||||
switch (IID) {
|
switch (IID) {
|
||||||
|
@ -305,7 +305,7 @@ void InferAddressSpaces::collectRewritableIntrinsicOperands(
|
||||||
// If V is an unvisited flat address expression, appends V to PostorderStack
|
// If V is an unvisited flat address expression, appends V to PostorderStack
|
||||||
// and marks it as visited.
|
// and marks it as visited.
|
||||||
void InferAddressSpaces::appendsFlatAddressExpressionToPostorderStack(
|
void InferAddressSpaces::appendsFlatAddressExpressionToPostorderStack(
|
||||||
Value *V, std::vector<std::pair<Value *, bool>> &PostorderStack,
|
Value *V, PostorderStackTy &PostorderStack,
|
||||||
DenseSet<Value *> &Visited) const {
|
DenseSet<Value *> &Visited) const {
|
||||||
assert(V->getType()->isPointerTy());
|
assert(V->getType()->isPointerTy());
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ void InferAddressSpaces::appendsFlatAddressExpressionToPostorderStack(
|
||||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||||
// TODO: Look in non-address parts, like icmp operands.
|
// TODO: Look in non-address parts, like icmp operands.
|
||||||
if (isAddressExpression(*CE) && Visited.insert(CE).second)
|
if (isAddressExpression(*CE) && Visited.insert(CE).second)
|
||||||
PostorderStack.push_back(std::make_pair(CE, false));
|
PostorderStack.emplace_back(CE, false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ void InferAddressSpaces::appendsFlatAddressExpressionToPostorderStack(
|
||||||
if (isAddressExpression(*V) &&
|
if (isAddressExpression(*V) &&
|
||||||
V->getType()->getPointerAddressSpace() == FlatAddrSpace) {
|
V->getType()->getPointerAddressSpace() == FlatAddrSpace) {
|
||||||
if (Visited.insert(V).second) {
|
if (Visited.insert(V).second) {
|
||||||
PostorderStack.push_back(std::make_pair(V, false));
|
PostorderStack.emplace_back(V, false);
|
||||||
|
|
||||||
Operator *Op = cast<Operator>(V);
|
Operator *Op = cast<Operator>(V);
|
||||||
for (unsigned I = 0, E = Op->getNumOperands(); I != E; ++I) {
|
for (unsigned I = 0, E = Op->getNumOperands(); I != E; ++I) {
|
||||||
|
@ -341,7 +341,7 @@ std::vector<WeakTrackingVH>
|
||||||
InferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
|
InferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
|
||||||
// This function implements a non-recursive postorder traversal of a partial
|
// This function implements a non-recursive postorder traversal of a partial
|
||||||
// use-def graph of function F.
|
// use-def graph of function F.
|
||||||
std::vector<std::pair<Value *, bool>> PostorderStack;
|
PostorderStackTy PostorderStack;
|
||||||
// The set of visited expressions.
|
// The set of visited expressions.
|
||||||
DenseSet<Value *> Visited;
|
DenseSet<Value *> Visited;
|
||||||
|
|
||||||
|
@ -388,17 +388,17 @@ InferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
|
||||||
|
|
||||||
std::vector<WeakTrackingVH> Postorder; // The resultant postorder.
|
std::vector<WeakTrackingVH> Postorder; // The resultant postorder.
|
||||||
while (!PostorderStack.empty()) {
|
while (!PostorderStack.empty()) {
|
||||||
Value *TopVal = PostorderStack.back().first;
|
Value *TopVal = PostorderStack.back().getPointer();
|
||||||
// If the operands of the expression on the top are already explored,
|
// If the operands of the expression on the top are already explored,
|
||||||
// adds that expression to the resultant postorder.
|
// adds that expression to the resultant postorder.
|
||||||
if (PostorderStack.back().second) {
|
if (PostorderStack.back().getInt()) {
|
||||||
if (TopVal->getType()->getPointerAddressSpace() == FlatAddrSpace)
|
if (TopVal->getType()->getPointerAddressSpace() == FlatAddrSpace)
|
||||||
Postorder.push_back(TopVal);
|
Postorder.push_back(TopVal);
|
||||||
PostorderStack.pop_back();
|
PostorderStack.pop_back();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Otherwise, adds its operands to the stack and explores them.
|
// Otherwise, adds its operands to the stack and explores them.
|
||||||
PostorderStack.back().second = true;
|
PostorderStack.back().setInt(true);
|
||||||
for (Value *PtrOperand : getPointerOperands(*TopVal)) {
|
for (Value *PtrOperand : getPointerOperands(*TopVal)) {
|
||||||
appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
|
appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
|
||||||
Visited);
|
Visited);
|
||||||
|
|
Loading…
Reference in New Issue