Bit-pack some pairs. No functionlity change intended.

This commit is contained in:
Benjamin Kramer 2020-04-21 20:09:30 +02:00
parent cca545ce46
commit 9a08c30705
3 changed files with 39 additions and 37 deletions

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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);