void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs, InstructionTemplate &IT) { for (const Variable &Var : IT.Instr.Variables) { llvm::MCOperand &AssignedValue = IT.getValueFor(Var); if (!AssignedValue.isValid()) randomize(IT.Instr, Var, AssignedValue, ForbiddenRegs); } }
static void setRegisterOperandValue(const RegisterOperandAssignment &ROV, InstructionTemplate &IB) { assert(ROV.Op); if (ROV.Op->isExplicit()) { auto &AssignedValue = IB.getValueFor(*ROV.Op); if (AssignedValue.isValid()) { assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg); return; } AssignedValue = llvm::MCOperand::createReg(ROV.Reg); } else { assert(ROV.Op->isImplicitReg()); assert(ROV.Reg == ROV.Op->getImplicitReg()); } }
static std::vector<InstructionTemplate> generateSnippetUsingStaticRenaming( const LLVMState &State, const InstructionTemplate &IT, const ArrayRef<const Variable *> TiedVariables, const BitVector *ScratchSpaceAliasedRegs) { std::vector<InstructionTemplate> Instructions; // Assign registers to variables in a round-robin manner. This is simple but // ensures that the most register-constrained variable does not get starved. std::vector<BitVector> PossibleRegsForVar; for (const Variable *Var : TiedVariables) { assert(Var); const Operand &Op = IT.Instr.getPrimaryOperand(*Var); assert(Op.isReg()); BitVector PossibleRegs = State.getRATC().emptyRegisters(); if (ScratchSpaceAliasedRegs) { PossibleRegs |= *ScratchSpaceAliasedRegs; } PossibleRegs.flip(); PossibleRegs &= Op.getRegisterAliasing().sourceBits(); PossibleRegsForVar.push_back(std::move(PossibleRegs)); } SmallVector<int, 2> Iterators(TiedVariables.size(), 0); while (true) { InstructionTemplate TmpIT = IT; // Find a possible register for each variable in turn, marking the // register as taken. for (size_t VarId = 0; VarId < TiedVariables.size(); ++VarId) { const int NextPossibleReg = PossibleRegsForVar[VarId].find_next(Iterators[VarId]); if (NextPossibleReg <= 0) { return Instructions; } TmpIT.getValueFor(*TiedVariables[VarId]) = llvm::MCOperand::createReg(NextPossibleReg); // Bump iterator. Iterators[VarId] = NextPossibleReg; // Prevent other variables from using the register. for (BitVector &OtherPossibleRegs : PossibleRegsForVar) { OtherPossibleRegs.reset(NextPossibleReg); } } Instructions.push_back(std::move(TmpIT)); } }