diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h @@ -171,6 +171,13 @@ static ValueIDNum TombstoneValue; }; +/// Type for a table of values in a block. +using ValueTable = std::unique_ptr; + +/// Type for a table-of-table-of-values, i.e., the collection of either +/// live-in or live-out values for each block in the function. +using FuncValueTable = std::unique_ptr; + /// Thin wrapper around an integer -- designed to give more type safety to /// spill location numbers. class SpillLocationNo { @@ -507,7 +514,7 @@ /// Load values for each location from array of ValueIDNums. Take current /// bbnum just in case we read a value from a hitherto untouched register. - void loadFromArray(ValueIDNum *Locs, unsigned NewCurBB) { + void loadFromArray(ValueTable &Locs, unsigned NewCurBB) { CurBB = NewCurBB; // Iterate over all tracked locations, and load each locations live-in // value into our local index. @@ -915,8 +922,8 @@ extractSpillBaseRegAndOffset(const MachineInstr &MI); /// Observe a single instruction while stepping through a block. - void process(MachineInstr &MI, ValueIDNum **MLiveOuts = nullptr, - ValueIDNum **MLiveIns = nullptr); + void process(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns); /// Examines whether \p MI is a DBG_VALUE and notifies trackers. /// \returns true if MI was recognized and processed. @@ -924,8 +931,8 @@ /// Examines whether \p MI is a DBG_INSTR_REF and notifies trackers. /// \returns true if MI was recognized and processed. - bool transferDebugInstrRef(MachineInstr &MI, ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns); + bool transferDebugInstrRef(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns); /// Stores value-information about where this PHI occurred, and what /// instruction number is associated with it. @@ -957,13 +964,13 @@ /// \p InstrNum Debug instruction number defined by DBG_PHI instructions. /// \returns The machine value number at position Here, or None. Optional resolveDbgPHIs(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, MachineInstr &Here, - uint64_t InstrNum); + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, + MachineInstr &Here, uint64_t InstrNum); Optional resolveDbgPHIsImpl(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum); @@ -981,8 +988,8 @@ /// live-out arrays to the (initialized to zero) multidimensional arrays in /// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block /// number, the inner by LocIdx. - void buildMLocValueMap(MachineFunction &MF, ValueIDNum **MInLocs, - ValueIDNum **MOutLocs, + void buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs, + FuncValueTable &MOutLocs, SmallVectorImpl &MLocTransfer); /// Examine the stack indexes (i.e. offsets within the stack) to find the @@ -993,7 +1000,7 @@ /// the IDF of each register. void placeMLocPHIs(MachineFunction &MF, SmallPtrSetImpl &AllBlocks, - ValueIDNum **MInLocs, + FuncValueTable &MInLocs, SmallVectorImpl &MLocTransfer); /// Propagate variable values to blocks in the common case where there's @@ -1024,7 +1031,7 @@ /// is true, revisiting this block is necessary. bool mlocJoin(MachineBasicBlock &MBB, SmallPtrSet &Visited, - ValueIDNum **OutLocs, ValueIDNum *InLocs); + FuncValueTable &OutLocs, ValueTable &InLocs); /// Produce a set of blocks that are in the current lexical scope. This means /// those blocks that contain instructions "in" the scope, blocks where @@ -1052,11 +1059,11 @@ /// scope, but which do contain DBG_VALUEs, which VarLocBasedImpl tracks /// locations through. void buildVLocValueMap(const DILocation *DILoc, - const SmallSet &VarsWeCareAbout, - SmallPtrSetImpl &AssignBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, - ValueIDNum **MInLocs, - SmallVectorImpl &AllTheVLocs); + const SmallSet &VarsWeCareAbout, + SmallPtrSetImpl &AssignBlocks, + LiveInsT &Output, FuncValueTable &MOutLocs, + FuncValueTable &MInLocs, + SmallVectorImpl &AllTheVLocs); /// Attempt to eliminate un-necessary PHIs on entry to a block. Examines the /// live-in values coming from predecessors live-outs, and replaces any PHIs @@ -1074,7 +1081,7 @@ /// \returns Value ID of a machine PHI if an appropriate one is available. Optional pickVPHILoc(const MachineBasicBlock &MBB, const DebugVariable &Var, - const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs, + const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl &BlockOrders); /// Take collections of DBG_VALUE instructions stored in TTracker, and @@ -1104,7 +1111,7 @@ bool depthFirstVLocAndEmit( unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation, const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl &AllTheVLocs, MachineFunction &MF, DenseMap &AllVarsNumbering, const TargetPassConfig &TPC); diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -266,7 +266,7 @@ /// object fields to track variable locations as we step through the block. /// FIXME: could just examine mloctracker instead of passing in \p mlocs? void - loadInlocs(MachineBasicBlock &MBB, ValueIDNum *MLocs, + loadInlocs(MachineBasicBlock &MBB, ValueTable &MLocs, const SmallVectorImpl> &VLocs, unsigned NumLocs) { ActiveMLocs.clear(); @@ -1022,8 +1022,8 @@ } bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns) { + const ValueTable *MLiveOuts, + const ValueTable *MLiveIns) { if (!MI.isDebugRef()) return false; @@ -1782,8 +1782,8 @@ AllSeenFragments.insert(ThisFragment); } -void InstrRefBasedLDV::process(MachineInstr &MI, ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns) { +void InstrRefBasedLDV::process(MachineInstr &MI, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns) { // Try to interpret an MI as a debug or transfer instruction. Only if it's // none of these should we interpret it's register defs as new value // definitions. @@ -1833,7 +1833,10 @@ // Step through each instruction in this block. for (auto &MI : MBB) { - process(MI); + // Pass in an empty unique_ptr for the value tables when accumulating the + // machine transfer function. + process(MI, nullptr, nullptr); + // Also accumulate fragment map. if (MI.isDebugValue() || MI.isDebugRef()) accumulateFragmentMap(MI); @@ -1922,7 +1925,7 @@ bool InstrRefBasedLDV::mlocJoin( MachineBasicBlock &MBB, SmallPtrSet &Visited, - ValueIDNum **OutLocs, ValueIDNum *InLocs) { + FuncValueTable &OutLocs, ValueTable &InLocs) { LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n"); bool Changed = false; @@ -2023,7 +2026,7 @@ void InstrRefBasedLDV::placeMLocPHIs( MachineFunction &MF, SmallPtrSetImpl &AllBlocks, - ValueIDNum **MInLocs, SmallVectorImpl &MLocTransfer) { + FuncValueTable &MInLocs, SmallVectorImpl &MLocTransfer) { SmallVector StackUnits; findStackIndexInterference(StackUnits); @@ -2152,7 +2155,7 @@ } void InstrRefBasedLDV::buildMLocValueMap( - MachineFunction &MF, ValueIDNum **MInLocs, ValueIDNum **MOutLocs, + MachineFunction &MF, FuncValueTable &MInLocs, FuncValueTable &MOutLocs, SmallVectorImpl &MLocTransfer) { std::priority_queue, std::greater> @@ -2294,7 +2297,7 @@ Optional InstrRefBasedLDV::pickVPHILoc( const MachineBasicBlock &MBB, const DebugVariable &Var, - const LiveIdxT &LiveOuts, ValueIDNum **MOutLocs, + const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl &BlockOrders) { // Collect a set of locations from predecessor where its live-out value can // be found. @@ -2562,7 +2565,7 @@ void InstrRefBasedLDV::buildVLocValueMap( const DILocation *DILoc, const SmallSet &VarsWeCareAbout, SmallPtrSetImpl &AssignBlocks, LiveInsT &Output, - ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl &AllTheVLocs) { // This method is much like buildMLocValueMap: but focuses on a single // LexicalScope at a time. Pick out a set of blocks and variables that are @@ -2947,7 +2950,7 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit( unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation, const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks, - LiveInsT &Output, ValueIDNum **MOutLocs, ValueIDNum **MInLocs, + LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs, SmallVectorImpl &AllTheVLocs, MachineFunction &MF, DenseMap &AllVarsNumbering, const TargetPassConfig &TPC) { @@ -2956,15 +2959,8 @@ VTracker = nullptr; // No scopes? No variable locations. - if (!LS.getCurrentFunctionScope()) { - // FIXME: this is a sticking plaster to prevent a memory leak, these - // pointers will be automagically freed by being unique pointers, shortly. - for (unsigned int I = 0; I < MaxNumBlocks; ++I) { - delete[] MInLocs[I]; - delete[] MOutLocs[I]; - } + if (!LS.getCurrentFunctionScope()) return false; - } // Build map from block number to the last scope that uses the block. SmallVector EjectionMap; @@ -2988,17 +2984,14 @@ CurBB = BBNum; CurInst = 1; for (auto &MI : MBB) { - process(MI, MOutLocs, MInLocs); + process(MI, MOutLocs.get(), MInLocs.get()); TTracker->checkInstForNewValues(CurInst, MI.getIterator()); ++CurInst; } // Free machine-location tables for this block. - delete[] MInLocs[BBNum]; - delete[] MOutLocs[BBNum]; - // Make ourselves brittle to use-after-free errors. - MInLocs[BBNum] = nullptr; - MOutLocs[BBNum] = nullptr; + MInLocs[BBNum].reset(); + MOutLocs[BBNum].reset(); // We don't need live-in variable values for this block either. Output[BBNum].clear(); AllTheVLocs[BBNum].clear(); @@ -3066,16 +3059,6 @@ if (MOutLocs[MBB->getNumber()]) EjectBlock(*MBB); - // Finally, there might have been gaps in the block numbering, from dead - // blocks being deleted or folded. In those scenarios, we might allocate a - // block-table that's never ejected, meaning we have to free it at the end. - for (unsigned int I = 0; I < MaxNumBlocks; ++I) { - if (MInLocs[I]) { - delete[] MInLocs[I]; - delete[] MOutLocs[I]; - } - } - return emitTransfers(AllVarsNumbering); } @@ -3173,13 +3156,13 @@ // Allocate and initialize two array-of-arrays for the live-in and live-out // machine values. The outer dimension is the block number; while the inner // dimension is a LocIdx from MLocTracker. - ValueIDNum **MOutLocs = new ValueIDNum *[MaxNumBlocks]; - ValueIDNum **MInLocs = new ValueIDNum *[MaxNumBlocks]; + FuncValueTable MOutLocs = std::make_unique(MaxNumBlocks); + FuncValueTable MInLocs = std::make_unique(MaxNumBlocks); unsigned NumLocs = MTracker->getNumLocs(); for (int i = 0; i < MaxNumBlocks; ++i) { // These all auto-initialize to ValueIDNum::EmptyValue - MOutLocs[i] = new ValueIDNum[NumLocs]; - MInLocs[i] = new ValueIDNum[NumLocs]; + MOutLocs[i] = std::make_unique(NumLocs); + MInLocs[i] = std::make_unique(NumLocs); } // Solve the machine value dataflow problem using the MLocTransfer function, @@ -3216,7 +3199,7 @@ MTracker->loadFromArray(MInLocs[CurBB], CurBB); CurInst = 1; for (auto &MI : MBB) { - process(MI, MOutLocs, MInLocs); + process(MI, MOutLocs.get(), MInLocs.get()); ++CurInst; } MTracker->reset(); @@ -3271,12 +3254,6 @@ << " has " << MaxNumBlocks << " basic blocks and " << VarAssignCount << " variable assignments, exceeding limits.\n"); - - // Perform memory cleanup that emitLocations would do otherwise. - for (int Idx = 0; Idx < MaxNumBlocks; ++Idx) { - delete[] MOutLocs[Idx]; - delete[] MInLocs[Idx]; - } } else { // Optionally, solve the variable value problem and emit to blocks by using // a lexical-scope-depth search. It should be functionally identical to @@ -3286,10 +3263,6 @@ SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, AllVarsNumbering, *TPC); } - // Elements of these arrays will be deleted by emitLocations. - delete[] MOutLocs; - delete[] MInLocs; - delete MTracker; delete TTracker; MTracker = nullptr; @@ -3406,9 +3379,10 @@ /// Machine location where any PHI must occur. LocIdx Loc; /// Table of live-in machine value numbers for blocks / locations. - ValueIDNum **MLiveIns; + const ValueTable *MLiveIns; - LDVSSAUpdater(LocIdx L, ValueIDNum **MLiveIns) : Loc(L), MLiveIns(MLiveIns) {} + LDVSSAUpdater(LocIdx L, const ValueTable *MLiveIns) + : Loc(L), MLiveIns(MLiveIns) {} void reset() { for (auto &Block : BlockMap) @@ -3565,11 +3539,13 @@ } // end namespace llvm -Optional InstrRefBasedLDV::resolveDbgPHIs(MachineFunction &MF, - ValueIDNum **MLiveOuts, - ValueIDNum **MLiveIns, - MachineInstr &Here, - uint64_t InstrNum) { +Optional InstrRefBasedLDV::resolveDbgPHIs( + MachineFunction &MF, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum) { + assert(MLiveOuts && MLiveIns && + "Tried to resolve DBG_PHI before location " + "tables allocated?"); + // This function will be called twice per DBG_INSTR_REF, and might end up // computing lots of SSA information: memoize it. auto SeenDbgPHIIt = SeenDbgPHIs.find(&Here); @@ -3583,8 +3559,8 @@ } Optional InstrRefBasedLDV::resolveDbgPHIsImpl( - MachineFunction &MF, ValueIDNum **MLiveOuts, ValueIDNum **MLiveIns, - MachineInstr &Here, uint64_t InstrNum) { + MachineFunction &MF, const ValueTable *MLiveOuts, + const ValueTable *MLiveIns, MachineInstr &Here, uint64_t InstrNum) { // Pick out records of DBG_PHI instructions that have been observed. If there // are none, then we cannot compute a value number. auto RangePair = std::equal_range(DebugPHINumToValue.begin(), @@ -3691,7 +3667,7 @@ return None; ValueIDNum ValueToCheck; - ValueIDNum *BlockLiveOuts = MLiveOuts[PHIIt.first->BB.getNumber()]; + const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB.getNumber()]; auto VVal = ValidatedValues.find(PHIIt.first); if (VVal == ValidatedValues.end()) { diff --git a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp --- a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp +++ b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp @@ -175,21 +175,21 @@ } // Some routines for bouncing into LDV, - void buildMLocValueMap(ValueIDNum **MInLocs, ValueIDNum **MOutLocs, + void buildMLocValueMap(FuncValueTable &MInLocs, FuncValueTable &MOutLocs, SmallVectorImpl &MLocTransfer) { LDV->buildMLocValueMap(*MF, MInLocs, MOutLocs, MLocTransfer); } void placeMLocPHIs(MachineFunction &MF, SmallPtrSetImpl &AllBlocks, - ValueIDNum **MInLocs, + FuncValueTable &MInLocs, SmallVectorImpl &MLocTransfer) { LDV->placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer); } Optional pickVPHILoc(const MachineBasicBlock &MBB, const DebugVariable &Var, - const InstrRefBasedLDV::LiveIdxT &LiveOuts, ValueIDNum **MOutLocs, + const InstrRefBasedLDV::LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl &BlockOrders) { return LDV->pickVPHILoc(MBB, Var, LiveOuts, MOutLocs, BlockOrders); } @@ -203,14 +203,14 @@ void buildVLocValueMap(const DILocation *DILoc, const SmallSet &VarsWeCareAbout, SmallPtrSetImpl &AssignBlocks, - InstrRefBasedLDV::LiveInsT &Output, ValueIDNum **MOutLocs, - ValueIDNum **MInLocs, + InstrRefBasedLDV::LiveInsT &Output, FuncValueTable &MOutLocs, + FuncValueTable &MInLocs, SmallVectorImpl &AllTheVLocs) { LDV->buildVLocValueMap(DILoc, VarsWeCareAbout, AssignBlocks, Output, MOutLocs, MInLocs, AllTheVLocs); } - void initValueArray(ValueIDNum **Nums, unsigned Blks, unsigned Locs) { + void initValueArray(FuncValueTable &Nums, unsigned Blks, unsigned Locs) { for (unsigned int I = 0; I < Blks; ++I) for (unsigned int J = 0; J < Locs; ++J) Nums[I][J] = ValueIDNum::EmptyValue; @@ -481,6 +481,19 @@ unsigned MaxNumBlocks) { LDV->produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks); } + + std::pair + allocValueTables(unsigned Blocks, unsigned Locs) { + FuncValueTable MOutLocs = std::make_unique(Blocks); + FuncValueTable MInLocs = std::make_unique(Blocks); + + for (unsigned int I = 0; I < Blocks; ++I) { + MOutLocs[I] = std::make_unique(Locs); + MInLocs[I] = std::make_unique(Locs); + } + + return std::make_pair(std::move(MOutLocs), std::move(MInLocs)); + } }; TEST_F(InstrRefLDVTest, MTransferDefs) { @@ -898,41 +911,40 @@ // Set up live-in and live-out tables for this function: two locations (we // add one later) in a single block. - ValueIDNum InLocs[2], OutLocs[2]; - ValueIDNum *InLocsPtr[1] = {&InLocs[0]}; - ValueIDNum *OutLocsPtr[1] = {&OutLocs[0]}; + FuncValueTable MOutLocs, MInLocs; + std::tie(MOutLocs, MInLocs) = allocValueTables(1, 2); // Transfer function: nothing. SmallVector TransferFunc; TransferFunc.resize(1); // Try and build value maps... - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); // The result should be that RSP is marked as a live-in-PHI -- this represents // an argument. And as there's no transfer function, the block live-out should // be the same. - EXPECT_EQ(InLocs[0], ValueIDNum(0, 0, RspLoc)); - EXPECT_EQ(OutLocs[0], ValueIDNum(0, 0, RspLoc)); + EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc)); + EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 0, RspLoc)); // Try again, this time initialising the in-locs to be defined by an // instruction. The entry block should always be re-assigned to be the // arguments. - initValueArray(InLocsPtr, 1, 2); - initValueArray(OutLocsPtr, 1, 2); - InLocs[0] = ValueIDNum(0, 1, RspLoc); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0], ValueIDNum(0, 0, RspLoc)); - EXPECT_EQ(OutLocs[0], ValueIDNum(0, 0, RspLoc)); + initValueArray(MInLocs, 1, 2); + initValueArray(MOutLocs, 1, 2); + MInLocs[0][0] = ValueIDNum(0, 1, RspLoc); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc)); + EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 0, RspLoc)); // Now insert something into the transfer function to assign to the single // machine location. TransferFunc[0].insert({RspLoc, ValueIDNum(0, 1, RspLoc)}); - initValueArray(InLocsPtr, 1, 2); - initValueArray(OutLocsPtr, 1, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0], ValueIDNum(0, 0, RspLoc)); - EXPECT_EQ(OutLocs[0], ValueIDNum(0, 1, RspLoc)); + initValueArray(MInLocs, 1, 2); + initValueArray(MOutLocs, 1, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc)); + EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 1, RspLoc)); TransferFunc[0].clear(); // Add a new register to be tracked, and insert it into the transfer function @@ -941,13 +953,13 @@ LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); TransferFunc[0].insert({RspLoc, ValueIDNum(0, 1, RspLoc)}); TransferFunc[0].insert({RaxLoc, ValueIDNum(0, 0, RspLoc)}); - initValueArray(InLocsPtr, 1, 2); - initValueArray(OutLocsPtr, 1, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0], ValueIDNum(0, 0, RspLoc)); - EXPECT_EQ(InLocs[1], ValueIDNum(0, 0, RaxLoc)); - EXPECT_EQ(OutLocs[0], ValueIDNum(0, 1, RspLoc)); - EXPECT_EQ(OutLocs[1], ValueIDNum(0, 0, RspLoc)); // Rax contains RspLoc. + initValueArray(MInLocs, 1, 2); + initValueArray(MOutLocs, 1, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], ValueIDNum(0, 0, RspLoc)); + EXPECT_EQ(MInLocs[0][1], ValueIDNum(0, 0, RaxLoc)); + EXPECT_EQ(MOutLocs[0][0], ValueIDNum(0, 1, RspLoc)); + EXPECT_EQ(MOutLocs[0][1], ValueIDNum(0, 0, RspLoc)); // Rax contains RspLoc. TransferFunc[0].clear(); } @@ -965,9 +977,8 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum InLocs[4][2], OutLocs[4][2]; - ValueIDNum *InLocsPtr[4] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3]}; - ValueIDNum *OutLocsPtr[4] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(4, 2); // Transfer function: start with nothing. SmallVector TransferFunc; @@ -987,52 +998,52 @@ // With no transfer function, the live-in values to the entry block should // propagate to all live-outs and the live-ins to the two successor blocks. // IN ADDITION: this checks that the exit block doesn't get a PHI put in it. - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); // (Skipped writing out locations for $rax). // Check that a def of $rsp in the entry block will likewise reach all the // successors. TransferFunc[0].insert({RspLoc, RspDefInBlk0}); - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspDefInBlk0); - EXPECT_EQ(InLocs[2][0], RspDefInBlk0); - EXPECT_EQ(InLocs[3][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[0][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk0); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk0); TransferFunc[0].clear(); // Def in one branch of the diamond means that we need a PHI in the ret block TransferFunc[0].insert({RspLoc, RspDefInBlk0}); TransferFunc[1].insert({RspLoc, RspDefInBlk1}); - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); // This value map: like above, where RspDefInBlk0 is propagated through one // branch of the diamond, but is def'ed in the live-outs of the other. The // ret / merging block should have a PHI in its live-ins. - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspDefInBlk0); - EXPECT_EQ(InLocs[2][0], RspDefInBlk0); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[0][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3); TransferFunc[0].clear(); TransferFunc[1].clear(); @@ -1041,17 +1052,17 @@ TransferFunc[0].insert({RspLoc, RspDefInBlk0}); TransferFunc[1].insert({RspLoc, RspDefInBlk1}); TransferFunc[2].insert({RspLoc, RspDefInBlk2}); - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspDefInBlk0); - EXPECT_EQ(InLocs[2][0], RspDefInBlk0); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[0][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[3][0], RspPHIInBlk3); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3); TransferFunc[0].clear(); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1065,17 +1076,17 @@ TransferFunc[0].insert({RaxLoc, LiveInRsp}); TransferFunc[1].insert({RspLoc, RaxLiveInBlk1}); TransferFunc[2].insert({RspLoc, RaxLiveInBlk2}); - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspDefInBlk0); - EXPECT_EQ(InLocs[2][0], RspDefInBlk0); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], RspDefInBlk0); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk0); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], RspDefInBlk0); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); TransferFunc[0].clear(); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1119,8 +1130,8 @@ // There are other locations, for things like xmm0, which we're going to // ignore here. - ValueIDNum InLocs[4][10]; - ValueIDNum *InLocsPtr[4] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(4, 10); // Transfer function: start with nothing. SmallVector TransferFunc; @@ -1155,16 +1166,15 @@ // function. TransferFunc[1].insert({ALStackLoc, ALDefInBlk1}); TransferFunc[1].insert({HAXStackLoc, HAXDefInBlk1}); - initValueArray(InLocsPtr, 4, 10); - placeMLocPHIs(*MF, AllBlocks, InLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[3][ALStackLoc.asU64()], ALPHI); - EXPECT_EQ(InLocs[3][AXStackLoc.asU64()], AXPHI); - EXPECT_EQ(InLocs[3][EAXStackLoc.asU64()], EAXPHI); - EXPECT_EQ(InLocs[3][HAXStackLoc.asU64()], HAXPHI); - EXPECT_EQ(InLocs[3][RAXStackLoc.asU64()], RAXPHI); + initValueArray(MInLocs, 4, 10); + placeMLocPHIs(*MF, AllBlocks, MInLocs, TransferFunc); + EXPECT_EQ(MInLocs[3][ALStackLoc.asU64()], ALPHI); + EXPECT_EQ(MInLocs[3][AXStackLoc.asU64()], AXPHI); + EXPECT_EQ(MInLocs[3][EAXStackLoc.asU64()], EAXPHI); + EXPECT_EQ(MInLocs[3][HAXStackLoc.asU64()], HAXPHI); + EXPECT_EQ(MInLocs[3][RAXStackLoc.asU64()], RAXPHI); // AH should be left untouched, - EXPECT_EQ(InLocs[3][AHStackLoc.asU64()], ValueIDNum::EmptyValue); - + EXPECT_EQ(MInLocs[3][AHStackLoc.asU64()], ValueIDNum::EmptyValue); } TEST_F(InstrRefLDVTest, MLocSimpleLoop) { @@ -1182,9 +1192,8 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum InLocs[3][2], OutLocs[3][2]; - ValueIDNum *InLocsPtr[3] = {InLocs[0], InLocs[1], InLocs[2]}; - ValueIDNum *OutLocsPtr[3] = {OutLocs[0], OutLocs[1], OutLocs[2]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(3, 2); SmallVector TransferFunc; TransferFunc.resize(3); @@ -1200,15 +1209,15 @@ ValueIDNum RaxPHIInBlk2(RetBlk, 0, RaxLoc); // Begin test with all locations being live-through. - initValueArray(InLocsPtr, 3, 2); - initValueArray(OutLocsPtr, 3, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); + initValueArray(MInLocs, 3, 2); + initValueArray(MOutLocs, 3, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); // Add a def of $rsp to the loop block: it should be in the live-outs, but // should cause a PHI to be placed in the live-ins. Test the transfer function @@ -1217,22 +1226,22 @@ TransferFunc[1].insert({RspLoc, RspDefInBlk1}); TransferFunc[1].insert({RaxLoc, RspPHIInBlk1}); TransferFunc[2].insert({RspLoc, RaxPHIInBlk2}); - initValueArray(InLocsPtr, 3, 2); - initValueArray(OutLocsPtr, 3, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk1); + initValueArray(MInLocs, 3, 2); + initValueArray(MOutLocs, 3, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk1); // Check rax as well, - EXPECT_EQ(InLocs[0][1], LiveInRax); - EXPECT_EQ(InLocs[1][1], RaxPHIInBlk1); - EXPECT_EQ(InLocs[2][1], RspPHIInBlk1); - EXPECT_EQ(OutLocs[0][1], LiveInRax); - EXPECT_EQ(OutLocs[1][1], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][1], RspPHIInBlk1); + EXPECT_EQ(MInLocs[0][1], LiveInRax); + EXPECT_EQ(MInLocs[1][1], RaxPHIInBlk1); + EXPECT_EQ(MInLocs[2][1], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[0][1], LiveInRax); + EXPECT_EQ(MOutLocs[1][1], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][1], RspPHIInBlk1); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1243,22 +1252,22 @@ // to $rsp. TransferFunc[0].insert({RaxLoc, LiveInRsp}); TransferFunc[1].insert({RspLoc, RaxPHIInBlk1}); - initValueArray(InLocsPtr, 3, 2); - initValueArray(OutLocsPtr, 3, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); + initValueArray(MInLocs, 3, 2); + initValueArray(MOutLocs, 3, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); // Check $rax's values. - EXPECT_EQ(InLocs[0][1], LiveInRax); - EXPECT_EQ(InLocs[1][1], LiveInRsp); - EXPECT_EQ(InLocs[2][1], LiveInRsp); - EXPECT_EQ(OutLocs[0][1], LiveInRsp); - EXPECT_EQ(OutLocs[1][1], LiveInRsp); - EXPECT_EQ(OutLocs[2][1], LiveInRsp); + EXPECT_EQ(MInLocs[0][1], LiveInRax); + EXPECT_EQ(MInLocs[1][1], LiveInRsp); + EXPECT_EQ(MInLocs[2][1], LiveInRsp); + EXPECT_EQ(MOutLocs[0][1], LiveInRsp); + EXPECT_EQ(MOutLocs[1][1], LiveInRsp); + EXPECT_EQ(MOutLocs[2][1], LiveInRsp); TransferFunc[0].clear(); TransferFunc[1].clear(); } @@ -1282,11 +1291,8 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum InLocs[5][2], OutLocs[5][2]; - ValueIDNum *InLocsPtr[5] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3], - InLocs[4]}; - ValueIDNum *OutLocsPtr[5] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3], - OutLocs[4]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(5, 2); SmallVector TransferFunc; TransferFunc.resize(5); @@ -1305,56 +1311,56 @@ // Like the other tests: first ensure that if there's nothing in the transfer // function, then everything is live-through (check $rsp). - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(InLocs[4][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[4][0], LiveInRsp); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MInLocs[4][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[4][0], LiveInRsp); // A def in the inner loop means we should get PHIs at the heads of both // loops. Live-outs of the last three blocks will be the def, as it dominates // those. TransferFunc[2].insert({RspLoc, RspDefInBlk2}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspDefInBlk2); - EXPECT_EQ(InLocs[4][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk2); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk2); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk2); TransferFunc[2].clear(); // Adding a def to the outer loop header shouldn't affect this much -- the // live-out of block 1 changes. TransferFunc[1].insert({RspLoc, RspDefInBlk1}); TransferFunc[2].insert({RspLoc, RspDefInBlk2}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspDefInBlk2); - EXPECT_EQ(InLocs[4][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk2); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk2); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk2); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1364,19 +1370,19 @@ TransferFunc[1].insert({RspLoc, RspDefInBlk1}); TransferFunc[2].insert({RspLoc, RspDefInBlk2}); TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspDefInBlk2); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk2); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[1].clear(); TransferFunc[2].clear(); TransferFunc[3].clear(); @@ -1385,19 +1391,19 @@ // head and tail of the outer loop. The inner loop should be live-through. TransferFunc[1].insert({RspLoc, RspDefInBlk1}); TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspDefInBlk1); - EXPECT_EQ(InLocs[3][0], RspDefInBlk1); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[1].clear(); TransferFunc[3].clear(); @@ -1407,22 +1413,22 @@ TransferFunc[1].insert({RaxLoc, RspDefInBlk1}); TransferFunc[2].insert({RspLoc, RaxPHIInBlk2}); TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspDefInBlk1); - EXPECT_EQ(InLocs[3][0], RspDefInBlk1); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); // Look at raxes value in the relevant blocks, - EXPECT_EQ(InLocs[2][1], RspDefInBlk1); - EXPECT_EQ(OutLocs[1][1], RspDefInBlk1); + EXPECT_EQ(MInLocs[2][1], RspDefInBlk1); + EXPECT_EQ(MOutLocs[1][1], RspDefInBlk1); TransferFunc[1].clear(); TransferFunc[2].clear(); TransferFunc[3].clear(); @@ -1430,19 +1436,19 @@ // If we have a single def in the tail of the outer loop, that should produce // a PHI at the loop head, and be live-through the inner loop. TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[3].clear(); // And if we copy from $rsp to $rax in block 2, it should resolve to the PHI @@ -1451,20 +1457,20 @@ // inner loop. TransferFunc[2].insert({RaxLoc, RspPHIInBlk2}); TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); // Examining the values of rax, - EXPECT_EQ(InLocs[0][1], LiveInRax); - EXPECT_EQ(InLocs[1][1], RaxPHIInBlk1); - EXPECT_EQ(InLocs[2][1], RaxPHIInBlk2); - EXPECT_EQ(InLocs[3][1], RspPHIInBlk1); - EXPECT_EQ(InLocs[4][1], RspPHIInBlk1); - EXPECT_EQ(OutLocs[0][1], LiveInRax); - EXPECT_EQ(OutLocs[1][1], RaxPHIInBlk1); - EXPECT_EQ(OutLocs[2][1], RspPHIInBlk1); - EXPECT_EQ(OutLocs[3][1], RspPHIInBlk1); - EXPECT_EQ(OutLocs[4][1], RspPHIInBlk1); + EXPECT_EQ(MInLocs[0][1], LiveInRax); + EXPECT_EQ(MInLocs[1][1], RaxPHIInBlk1); + EXPECT_EQ(MInLocs[2][1], RaxPHIInBlk2); + EXPECT_EQ(MInLocs[3][1], RspPHIInBlk1); + EXPECT_EQ(MInLocs[4][1], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[0][1], LiveInRax); + EXPECT_EQ(MOutLocs[1][1], RaxPHIInBlk1); + EXPECT_EQ(MOutLocs[2][1], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[3][1], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[4][1], RspPHIInBlk1); TransferFunc[2].clear(); TransferFunc[3].clear(); } @@ -1487,11 +1493,8 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum InLocs[5][2], OutLocs[5][2]; - ValueIDNum *InLocsPtr[5] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3], - InLocs[4]}; - ValueIDNum *OutLocsPtr[5] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3], - OutLocs[4]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(5, 2); SmallVector TransferFunc; TransferFunc.resize(5); @@ -1509,71 +1512,71 @@ ValueIDNum RaxPHIInBlk2(Head2Blk, 0, RaxLoc); // As ever, test that everything is live-through if there are no defs. - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(InLocs[4][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[4][0], LiveInRsp); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MInLocs[4][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[4][0], LiveInRsp); // Putting a def in the 'join' block will cause us to have two distinct // PHIs in each loop head, then on entry to the join block. TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[3].clear(); // We should get the same behaviour if we put the def in either of the // loop heads -- it should force the other head to be a PHI. TransferFunc[1].insert({RspLoc, RspDefInBlk1}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(InLocs[4][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(OutLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[4][0], RspPHIInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[4][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspPHIInBlk3); TransferFunc[1].clear(); // Check symmetry, TransferFunc[2].insert({RspLoc, RspDefInBlk2}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(InLocs[4][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk2); - EXPECT_EQ(OutLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(OutLocs[4][0], RspPHIInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[4][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspPHIInBlk3); TransferFunc[2].clear(); // Test some scenarios where there _shouldn't_ be any PHIs created at heads. @@ -1585,19 +1588,19 @@ TransferFunc[1].insert({RspLoc, RaxPHIInBlk1}); TransferFunc[2].insert({RspLoc, RaxPHIInBlk2}); TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[0].clear(); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1609,19 +1612,19 @@ TransferFunc[0].insert({RaxLoc, LiveInRsp}); TransferFunc[1].insert({RspLoc, RaxPHIInBlk1}); TransferFunc[2].insert({RspLoc, RaxPHIInBlk2}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(InLocs[4][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[4][0], LiveInRsp); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MInLocs[4][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[4][0], LiveInRsp); TransferFunc[0].clear(); TransferFunc[1].clear(); TransferFunc[2].clear(); @@ -1646,11 +1649,8 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum InLocs[5][2], OutLocs[5][2]; - ValueIDNum *InLocsPtr[5] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3], - InLocs[4]}; - ValueIDNum *OutLocsPtr[5] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3], - OutLocs[4]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(5, 2); SmallVector TransferFunc; TransferFunc.resize(5); @@ -1667,55 +1667,55 @@ ValueIDNum RaxPHIInBlk3(Loop3Blk, 0, RaxLoc); // As ever, test that everything is live-through if there are no defs. - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], LiveInRsp); - EXPECT_EQ(InLocs[2][0], LiveInRsp); - EXPECT_EQ(InLocs[3][0], LiveInRsp); - EXPECT_EQ(InLocs[4][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], LiveInRsp); - EXPECT_EQ(OutLocs[2][0], LiveInRsp); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[4][0], LiveInRsp); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], LiveInRsp); + EXPECT_EQ(MInLocs[2][0], LiveInRsp); + EXPECT_EQ(MInLocs[3][0], LiveInRsp); + EXPECT_EQ(MInLocs[4][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], LiveInRsp); + EXPECT_EQ(MOutLocs[2][0], LiveInRsp); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[4][0], LiveInRsp); // A def in loop3 should cause PHIs in every loop block: they're all // reachable from each other. TransferFunc[3].insert({RspLoc, RspDefInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(InLocs[4][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk3); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk3); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk3); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk3); TransferFunc[3].clear(); // A def in loop1 should cause a PHI in loop1, but not the other blocks. // loop2 and loop3 are dominated by the def in loop1, so they should have // that value live-through. TransferFunc[1].insert({RspLoc, RspDefInBlk1}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspDefInBlk1); - EXPECT_EQ(InLocs[3][0], RspDefInBlk1); - EXPECT_EQ(InLocs[4][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[2][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[3][0], RspDefInBlk1); - EXPECT_EQ(OutLocs[4][0], RspDefInBlk1); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[3][0], RspDefInBlk1); + EXPECT_EQ(MInLocs[4][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[3][0], RspDefInBlk1); + EXPECT_EQ(MOutLocs[4][0], RspDefInBlk1); TransferFunc[1].clear(); // As with earlier tricks: copy $rsp to $rax in the entry block, then $rax @@ -1742,31 +1742,31 @@ // approach. PHIs will be left in $rsp on entry to each block. TransferFunc[0].insert({RaxLoc, LiveInRsp}); TransferFunc[3].insert({RspLoc, RaxPHIInBlk3}); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); - buildMLocValueMap(InLocsPtr, OutLocsPtr, TransferFunc); - EXPECT_EQ(InLocs[0][0], LiveInRsp); - EXPECT_EQ(InLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(InLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(InLocs[3][0], RspPHIInBlk3); - EXPECT_EQ(InLocs[4][0], LiveInRsp); - EXPECT_EQ(OutLocs[0][0], LiveInRsp); - EXPECT_EQ(OutLocs[1][0], RspPHIInBlk1); - EXPECT_EQ(OutLocs[2][0], RspPHIInBlk2); - EXPECT_EQ(OutLocs[3][0], LiveInRsp); - EXPECT_EQ(OutLocs[4][0], LiveInRsp); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); + buildMLocValueMap(MInLocs, MOutLocs, TransferFunc); + EXPECT_EQ(MInLocs[0][0], LiveInRsp); + EXPECT_EQ(MInLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MInLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MInLocs[3][0], RspPHIInBlk3); + EXPECT_EQ(MInLocs[4][0], LiveInRsp); + EXPECT_EQ(MOutLocs[0][0], LiveInRsp); + EXPECT_EQ(MOutLocs[1][0], RspPHIInBlk1); + EXPECT_EQ(MOutLocs[2][0], RspPHIInBlk2); + EXPECT_EQ(MOutLocs[3][0], LiveInRsp); + EXPECT_EQ(MOutLocs[4][0], LiveInRsp); // Check $rax's value. It should have $rsps value from the entry block // onwards. - EXPECT_EQ(InLocs[0][1], LiveInRax); - EXPECT_EQ(InLocs[1][1], LiveInRsp); - EXPECT_EQ(InLocs[2][1], LiveInRsp); - EXPECT_EQ(InLocs[3][1], LiveInRsp); - EXPECT_EQ(InLocs[4][1], LiveInRsp); - EXPECT_EQ(OutLocs[0][1], LiveInRsp); - EXPECT_EQ(OutLocs[1][1], LiveInRsp); - EXPECT_EQ(OutLocs[2][1], LiveInRsp); - EXPECT_EQ(OutLocs[3][1], LiveInRsp); - EXPECT_EQ(OutLocs[4][1], LiveInRsp); + EXPECT_EQ(MInLocs[0][1], LiveInRax); + EXPECT_EQ(MInLocs[1][1], LiveInRsp); + EXPECT_EQ(MInLocs[2][1], LiveInRsp); + EXPECT_EQ(MInLocs[3][1], LiveInRsp); + EXPECT_EQ(MInLocs[4][1], LiveInRsp); + EXPECT_EQ(MOutLocs[0][1], LiveInRsp); + EXPECT_EQ(MOutLocs[1][1], LiveInRsp); + EXPECT_EQ(MOutLocs[2][1], LiveInRsp); + EXPECT_EQ(MOutLocs[3][1], LiveInRsp); + EXPECT_EQ(MOutLocs[4][1], LiveInRsp); } TEST_F(InstrRefLDVTest, pickVPHILocDiamond) { @@ -1782,10 +1782,10 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum OutLocs[4][2]; - ValueIDNum *OutLocsPtr[4] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(4, 2); - initValueArray(OutLocsPtr, 4, 2); + initValueArray(MOutLocs, 4, 2); unsigned EntryBlk = 0, Br2Blk = 2, RetBlk = 3; @@ -1809,15 +1809,15 @@ Preds.push_back(Pred); // Specify the live-outs around the joining block. - OutLocs[1][0] = LiveInRsp; - OutLocs[2][0] = LiveInRax; + MOutLocs[1][0] = LiveInRsp; + MOutLocs[2][0] = LiveInRax; Optional Result; // Simple case: join two distinct values on entry to the block. VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); // Should have picked a PHI in $rsp in block 3. EXPECT_TRUE(Result); if (Result) { @@ -1828,7 +1828,7 @@ // successfully join. The CFG merge would select the right values, but in // the wrong conditions. std::swap(VLiveOuts[1], VLiveOuts[2]); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Swap back, @@ -1836,19 +1836,19 @@ // Setting one of these to being a constant should prohibit merging. VLiveOuts[1].Kind = DbgValue::Const; VLiveOuts[1].MO = MachineOperand::CreateImm(0); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Seeing both to being a constant -> still prohibit, it shouldn't become // a value in the register file anywhere. VLiveOuts[2] = VLiveOuts[1]; - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // NoVals shouldn't join with anything else. VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::NoVal); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // We might merge in another VPHI in such a join. Present pickVPHILoc with @@ -1858,25 +1858,25 @@ VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI); EXPECT_EQ(VLiveOuts[2].ID, ValueIDNum::EmptyValue); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // However, if we know the value of the incoming VPHI, we can search for its // location. Use a PHI machine-value for doing this, as VPHIs should always // have PHI values, or they should have been eliminated. - OutLocs[2][0] = RspPHIInBlk2; + MOutLocs[2][0] = RspPHIInBlk2; VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI); VLiveOuts[2].ID = RspPHIInBlk2; // Set location where PHI happens. - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_TRUE(Result); if (Result) { EXPECT_EQ(*Result, RspPHIInBlk3); } // If that value isn't available from that block, don't join. - OutLocs[2][0] = LiveInRsp; - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[2][0] = LiveInRsp; + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Check that we don't pick values when the properties disagree, for example @@ -1886,13 +1886,13 @@ DbgValueProperties PropsWithExpr(NewExpr, false); VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); DbgValueProperties PropsWithIndirect(EmptyExpr, true); VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def); - Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); } @@ -1911,10 +1911,10 @@ Register RAX = getRegByName("RAX"); LocIdx RaxLoc = MTracker->lookupOrTrackRegister(RAX); - ValueIDNum OutLocs[3][2]; - ValueIDNum *OutLocsPtr[4] = {OutLocs[0], OutLocs[1], OutLocs[2]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(3, 2); - initValueArray(OutLocsPtr, 3, 2); + initValueArray(MOutLocs, 3, 2); unsigned EntryBlk = 0, LoopBlk = 1; @@ -1937,15 +1937,15 @@ Preds.push_back(Pred); // Specify the live-outs around the joining block. - OutLocs[0][0] = LiveInRsp; - OutLocs[1][0] = LiveInRax; + MOutLocs[0][0] = LiveInRsp; + MOutLocs[1][0] = LiveInRax; Optional Result; // See that we can merge as normal on a backedge. VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); // Should have picked a PHI in $rsp in block 1. EXPECT_TRUE(Result); if (Result) { @@ -1953,22 +1953,22 @@ } // And that, if the desired values aren't available, we don't merge. - OutLocs[1][0] = LiveInRsp; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[1][0] = LiveInRsp; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Test the backedge behaviour: PHIs that feed back into themselves can // carry this variables value. Feed in LiveInRsp in both $rsp and $rax // from the entry block, but only put an appropriate backedge PHI in $rax. // Only the $rax location can form the correct PHI. - OutLocs[0][0] = LiveInRsp; - OutLocs[0][1] = LiveInRsp; - OutLocs[1][0] = RaxPHIInBlk1; - OutLocs[1][1] = RaxPHIInBlk1; + MOutLocs[0][0] = LiveInRsp; + MOutLocs[0][1] = LiveInRsp; + MOutLocs[1][0] = RaxPHIInBlk1; + MOutLocs[1][1] = RaxPHIInBlk1; VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); // Crucially, a VPHI originating in this block: VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_TRUE(Result); if (Result) { EXPECT_EQ(*Result, RaxPHIInBlk1); @@ -1976,16 +1976,16 @@ // Merging should not be permitted if there's a usable PHI on the backedge, // but it's in the wrong place. (Overwrite $rax). - OutLocs[1][1] = LiveInRax; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[1][1] = LiveInRax; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Additionally, if the VPHI coming back on the loop backedge isn't from // this block (block 1), we can't merge it. - OutLocs[1][1] = RaxPHIInBlk1; + MOutLocs[1][1] = RaxPHIInBlk1; VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[1] = DbgValue(0, EmptyProps, DbgValue::VPHI); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); } @@ -2011,10 +2011,10 @@ Register RBX = getRegByName("RBX"); LocIdx RbxLoc = MTracker->lookupOrTrackRegister(RBX); - ValueIDNum OutLocs[5][3]; - ValueIDNum *OutLocsPtr[5] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3], OutLocs[4]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(5, 3); - initValueArray(OutLocsPtr, 5, 3); + initValueArray(MOutLocs, 5, 3); unsigned EntryBlk = 0, Loop1Blk = 1; @@ -2043,9 +2043,9 @@ // Specify the live-outs around the joining block. Incoming edges from the // entry block, self, and loop2. - OutLocs[0][0] = LiveInRsp; - OutLocs[1][0] = LiveInRax; - OutLocs[2][0] = LiveInRbx; + MOutLocs[0][0] = LiveInRsp; + MOutLocs[1][0] = LiveInRax; + MOutLocs[2][0] = LiveInRbx; Optional Result; @@ -2053,7 +2053,7 @@ VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def); VLiveOuts[2] = DbgValue(LiveInRbx, EmptyProps, DbgValue::Def); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); // Should have picked a PHI in $rsp in block 1. EXPECT_TRUE(Result); if (Result) { @@ -2061,20 +2061,20 @@ } // Check too that permuting the live-out locations prevents merging - OutLocs[0][0] = LiveInRax; - OutLocs[1][0] = LiveInRbx; - OutLocs[2][0] = LiveInRsp; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[0][0] = LiveInRax; + MOutLocs[1][0] = LiveInRbx; + MOutLocs[2][0] = LiveInRsp; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); - OutLocs[0][0] = LiveInRsp; - OutLocs[1][0] = LiveInRax; - OutLocs[2][0] = LiveInRbx; + MOutLocs[0][0] = LiveInRsp; + MOutLocs[1][0] = LiveInRax; + MOutLocs[2][0] = LiveInRbx; // Feeding a PHI back on one backedge shouldn't merge (block 1 self backedge // wants LiveInRax). - OutLocs[1][0] = RspPHIInBlk1; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[1][0] = RspPHIInBlk1; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // If the variables value on that edge is a VPHI feeding into itself, that's @@ -2082,18 +2082,18 @@ VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI); VLiveOuts[2] = DbgValue(LiveInRbx, EmptyProps, DbgValue::Def); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_TRUE(Result); if (Result) { EXPECT_EQ(*Result, RspPHIInBlk1); } // Likewise: the other backedge being a VPHI from block 1 should be accepted. - OutLocs[2][0] = RspPHIInBlk1; + MOutLocs[2][0] = RspPHIInBlk1; VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def); VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI); VLiveOuts[2] = DbgValue(1, EmptyProps, DbgValue::VPHI); - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_TRUE(Result); if (Result) { EXPECT_EQ(*Result, RspPHIInBlk1); @@ -2102,32 +2102,32 @@ // Here's where it becomes tricky: we should not merge if there are two // _distinct_ backedge PHIs. We can't have a PHI that happens in both rsp // and rax for example. We can only pick one location as the live-in. - OutLocs[2][0] = RaxPHIInBlk1; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[2][0] = RaxPHIInBlk1; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // The above test sources correct machine-PHI-value from two places. Now // try with one machine-PHI-value, but placed in two different locations // on the backedge. Again, we can't merge a location here, there's no // location that works on all paths. - OutLocs[0][0] = LiveInRsp; - OutLocs[1][0] = RspPHIInBlk1; - OutLocs[2][0] = LiveInRsp; - OutLocs[2][1] = RspPHIInBlk1; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[0][0] = LiveInRsp; + MOutLocs[1][0] = RspPHIInBlk1; + MOutLocs[2][0] = LiveInRsp; + MOutLocs[2][1] = RspPHIInBlk1; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_FALSE(Result); // Scatter various PHI values across the available locations. Only rbx (loc 2) // has the right value in both backedges -- that's the loc that should be // picked. - OutLocs[0][2] = LiveInRsp; - OutLocs[1][0] = RspPHIInBlk1; - OutLocs[1][1] = RaxPHIInBlk1; - OutLocs[1][2] = RbxPHIInBlk1; - OutLocs[2][0] = LiveInRsp; - OutLocs[2][1] = RspPHIInBlk1; - OutLocs[2][2] = RbxPHIInBlk1; - Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds); + MOutLocs[0][2] = LiveInRsp; + MOutLocs[1][0] = RspPHIInBlk1; + MOutLocs[1][1] = RaxPHIInBlk1; + MOutLocs[1][2] = RbxPHIInBlk1; + MOutLocs[2][0] = LiveInRsp; + MOutLocs[2][1] = RspPHIInBlk1; + MOutLocs[2][2] = RbxPHIInBlk1; + Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, MOutLocs, Preds); EXPECT_TRUE(Result); if (Result) { EXPECT_EQ(*Result, RbxPHIInBlk1); @@ -2493,12 +2493,11 @@ ASSERT_TRUE(MTracker->getNumLocs() == 1); LocIdx RspLoc(0); - ValueIDNum InLocs[2], OutLocs[2]; - ValueIDNum *InLocsPtr[1] = {&InLocs[0]}; - ValueIDNum *OutLocsPtr[1] = {&OutLocs[0]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(1, 2); ValueIDNum LiveInRsp = ValueIDNum(0, 0, RspLoc); - InLocs[0] = OutLocs[0] = LiveInRsp; + MInLocs[0][0] = MOutLocs[0][0] = LiveInRsp; DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); @@ -2521,14 +2520,14 @@ // Test that, with no assignments at all, no mappings are created for the // variable in this function. buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output.size(), 0ul); // If we put an assignment in the transfer function, that should... well, // do nothing, because we don't store the live-outs. VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output.size(), 0ul); // There is pretty much nothing else of interest to test with a single block. @@ -2554,12 +2553,11 @@ ValueIDNum LiveInRax = ValueIDNum(EntryBlk, 0, RaxLoc); ValueIDNum RspPHIInBlk3 = ValueIDNum(RetBlk, 0, RspLoc); - ValueIDNum InLocs[4][2], OutLocs[4][2]; - ValueIDNum *InLocsPtr[4] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3]}; - ValueIDNum *OutLocsPtr[4] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(4, 2); - initValueArray(InLocsPtr, 4, 2); - initValueArray(OutLocsPtr, 4, 2); + initValueArray(MInLocs, 4, 2); + initValueArray(MOutLocs, 4, 2); DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); @@ -2584,8 +2582,8 @@ // Start off with LiveInRsp in every location. for (unsigned int I = 0; I < 4; ++I) { - InLocs[I][0] = InLocs[I][1] = LiveInRsp; - OutLocs[I][0] = OutLocs[I][1] = LiveInRsp; + MInLocs[I][0] = MInLocs[I][1] = LiveInRsp; + MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp; } auto ClearOutputs = [&]() { @@ -2596,7 +2594,7 @@ // No assignments -> no values. buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2606,7 +2604,7 @@ // produce any live-ins. VLocs[3].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2618,7 +2616,7 @@ VLocs[3].Vars.clear(); VLocs[2].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2628,7 +2626,7 @@ VLocs[1].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2640,7 +2638,7 @@ // values through to all other blocks, as it dominates. VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2660,7 +2658,7 @@ // values through to all other blocks, as it dominates. VLocs[0].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2679,7 +2677,7 @@ VLocs[1].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[2].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2695,7 +2693,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(EmptyProps, DbgValue::Undef)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2714,7 +2712,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2729,11 +2727,11 @@ // But on the other hand, if there's a location in the register file where // those two values can be joined, do so. - OutLocs[1][0] = LiveInRax; + MOutLocs[1][0] = LiveInRax; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2772,12 +2770,11 @@ ValueIDNum RspDefInBlk1 = ValueIDNum(LoopBlk, 1, RspLoc); ValueIDNum RaxPHIInBlk1 = ValueIDNum(LoopBlk, 0, RaxLoc); - ValueIDNum InLocs[3][2], OutLocs[3][2]; - ValueIDNum *InLocsPtr[3] = {InLocs[0], InLocs[1], InLocs[2]}; - ValueIDNum *OutLocsPtr[3] = {OutLocs[0], OutLocs[1], OutLocs[2]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(3, 2); - initValueArray(InLocsPtr, 3, 2); - initValueArray(OutLocsPtr, 3, 2); + initValueArray(MInLocs, 3, 2); + initValueArray(MOutLocs, 3, 2); DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); @@ -2797,8 +2794,8 @@ // Start off with LiveInRsp in every location. for (unsigned int I = 0; I < 3; ++I) { - InLocs[I][0] = InLocs[I][1] = LiveInRsp; - OutLocs[I][0] = OutLocs[I][1] = LiveInRsp; + MInLocs[I][0] = MInLocs[I][1] = LiveInRsp; + MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp; } auto ClearOutputs = [&]() { @@ -2810,7 +2807,7 @@ // Easy starter: a dominating assign should propagate to all blocks. VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2826,7 +2823,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(EmptyProps, DbgValue::Undef)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -2838,7 +2835,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2855,7 +2852,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2867,12 +2864,12 @@ // Install a completely unrelated PHI value, that we should not join on. Try // with unrelated assign in loop block again. - InLocs[1][0] = RspPHIInBlk1; - OutLocs[1][0] = RspDefInBlk1; + MInLocs[1][0] = RspPHIInBlk1; + MOutLocs[1][0] = RspDefInBlk1; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2884,12 +2881,12 @@ // Now, if we assign RspDefInBlk1 in the loop block, we should be able to // find the appropriate PHI. - InLocs[1][0] = RspPHIInBlk1; - OutLocs[1][0] = RspDefInBlk1; + MInLocs[1][0] = RspPHIInBlk1; + MOutLocs[1][0] = RspDefInBlk1; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(RspDefInBlk1, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2903,14 +2900,14 @@ // If the PHI happens in a different location, the live-in should happen // there. - InLocs[1][0] = LiveInRsp; - OutLocs[1][0] = LiveInRsp; - InLocs[1][1] = RaxPHIInBlk1; - OutLocs[1][1] = RspDefInBlk1; + MInLocs[1][0] = LiveInRsp; + MOutLocs[1][0] = LiveInRsp; + MInLocs[1][1] = RaxPHIInBlk1; + MOutLocs[1][1] = RspDefInBlk1; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(RspDefInBlk1, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2925,14 +2922,14 @@ // The PHI happening in both places should be handled too. Exactly where // isn't important, but if the location picked changes, this test will let // you know. - InLocs[1][0] = RaxPHIInBlk1; - OutLocs[1][0] = RspDefInBlk1; - InLocs[1][1] = RaxPHIInBlk1; - OutLocs[1][1] = RspDefInBlk1; + MInLocs[1][0] = RaxPHIInBlk1; + MOutLocs[1][0] = RspDefInBlk1; + MInLocs[1][1] = RaxPHIInBlk1; + MOutLocs[1][1] = RspDefInBlk1; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(RspDefInBlk1, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2959,14 +2956,14 @@ // joined at some location by the control flow. // [This test input would never occur naturally, the machine-PHI would be // eliminated] - InLocs[1][0] = RspPHIInBlk1; - OutLocs[1][0] = RspPHIInBlk1; - InLocs[1][1] = LiveInRax; - OutLocs[1][1] = LiveInRax; + MInLocs[1][0] = RspPHIInBlk1; + MOutLocs[1][0] = RspPHIInBlk1; + MInLocs[1][1] = LiveInRax; + MOutLocs[1][1] = LiveInRax; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(RspPHIInBlk1, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -2980,12 +2977,12 @@ // Test that we can eliminate PHIs. A PHI will be placed at the loop head // because there's a def in in. - InLocs[1][0] = LiveInRsp; - OutLocs[1][0] = LiveInRsp; + MInLocs[1][0] = LiveInRsp; + MOutLocs[1][0] = LiveInRsp; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -3026,12 +3023,11 @@ ValueIDNum RspPHIInBlk2 = ValueIDNum(Loop2Blk, 0, RspLoc); ValueIDNum RspDefInBlk2 = ValueIDNum(Loop2Blk, 1, RspLoc); - ValueIDNum InLocs[5][2], OutLocs[5][2]; - ValueIDNum *InLocsPtr[5] = {InLocs[0], InLocs[1], InLocs[2], InLocs[3], InLocs[4]}; - ValueIDNum *OutLocsPtr[5] = {OutLocs[0], OutLocs[1], OutLocs[2], OutLocs[3], OutLocs[4]}; + FuncValueTable MInLocs, MOutLocs; + std::tie(MInLocs, MOutLocs) = allocValueTables(5, 2); - initValueArray(InLocsPtr, 5, 2); - initValueArray(OutLocsPtr, 5, 2); + initValueArray(MInLocs, 5, 2); + initValueArray(MOutLocs, 5, 2); DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); @@ -3053,8 +3049,8 @@ // Start off with LiveInRsp in every location. for (unsigned int I = 0; I < 5; ++I) { - InLocs[I][0] = InLocs[I][1] = LiveInRsp; - OutLocs[I][0] = OutLocs[I][1] = LiveInRsp; + MInLocs[I][0] = MInLocs[I][1] = LiveInRsp; + MOutLocs[I][0] = MOutLocs[I][1] = LiveInRsp; } auto ClearOutputs = [&]() { @@ -3066,7 +3062,7 @@ // A dominating assign should propagate to all blocks. VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -3088,7 +3084,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[2].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -3106,7 +3102,7 @@ // in dominated blocks. VLocs[2].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -3124,7 +3120,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[3].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -3139,7 +3135,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[1].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); ASSERT_EQ(Output[2].size(), 1ul); @@ -3161,7 +3157,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[2].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 1ul); EXPECT_EQ(Output[2].size(), 1ul); @@ -3183,8 +3179,8 @@ // loop head, we could find a live-in location for the inner loop. But because // the outer loop has no PHI, we can't find a variable value for outer loop // head, so can't have a live-in value for the inner loop head. - InLocs[2][0] = RspPHIInBlk2; - OutLocs[2][0] = LiveInRax; + MInLocs[2][0] = RspPHIInBlk2; + MOutLocs[2][0] = LiveInRax; // NB: all other machine locations are LiveInRsp, disallowing a PHI in block // one. Even though RspPHIInBlk2 isn't available later in the function, we // should still produce a live-in value. The fact it's unavailable is a @@ -3192,7 +3188,7 @@ VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[2].Vars.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); EXPECT_EQ(Output[1].size(), 0ul); EXPECT_EQ(Output[2].size(), 0ul); @@ -3209,16 +3205,16 @@ // Have an assignment in inner loop that can have a PHI resolved; and add a // machine value PHI to the outer loop head, so that we can find a location // all the way through the function. - InLocs[1][0] = RspPHIInBlk1; - OutLocs[1][0] = RspPHIInBlk1; - InLocs[2][0] = RspPHIInBlk2; - OutLocs[2][0] = RspDefInBlk2; - InLocs[3][0] = RspDefInBlk2; - OutLocs[3][0] = RspDefInBlk2; + MInLocs[1][0] = RspPHIInBlk1; + MOutLocs[1][0] = RspPHIInBlk1; + MInLocs[2][0] = RspPHIInBlk2; + MOutLocs[2][0] = RspDefInBlk2; + MInLocs[3][0] = RspDefInBlk2; + MOutLocs[3][0] = RspDefInBlk2; VLocs[0].Vars.insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLocs[2].Vars.insert({Var, DbgValue(RspDefInBlk2, EmptyProps, DbgValue::Def)}); buildVLocValueMap(OutermostLoc, AllVars, AssignBlocks, Output, - OutLocsPtr, InLocsPtr, VLocs); + MOutLocs, MInLocs, VLocs); EXPECT_EQ(Output[0].size(), 0ul); ASSERT_EQ(Output[1].size(), 1ul); ASSERT_EQ(Output[2].size(), 1ul);