unordered_multimap<const char*, Value*>& ArgumentRecovery::exposeAllRegisters(llvm::Function* fn) { auto iter = registerAddresses.find(fn); if (iter != registerAddresses.end()) { return iter->second; } auto& addresses = registerAddresses[fn]; if (fn->isDeclaration()) { // If a function has no body, it doesn't need a register map. return addresses; } Argument* firstArg = fn->arg_begin(); assert(isStructType(firstArg)); // Get explicitly-used GEPs const auto& target = getAnalysis<TargetInfo>(); for (User* user : firstArg->users()) { if (auto gep = dyn_cast<GetElementPtrInst>(user)) { const char* name = target.registerName(*gep); const char* largestRegister = target.largestOverlappingRegister(name); addresses.insert({largestRegister, gep}); } } // Synthesize GEPs for implicitly-used registers. // Implicit uses are when a function callee uses a register without there being a reference in the caller. // This happens either because the parameter is passed through, or because the register is a scratch register that // the caller doesn't use itself. auto insertionPoint = fn->begin()->begin(); auto& regUse = getAnalysis<RegisterUse>(); const auto& modRefInfo = *regUse.getModRefInfo(fn); for (const auto& pair : modRefInfo) { if ((pair.second & RegisterUse::ModRef) != 0 && addresses.find(pair.first) == addresses.end()) { // Need a GEP here, because the function ModRefs the register implicitly. GetElementPtrInst* synthesizedGep = target.getRegister(firstArg, pair.first); synthesizedGep->insertBefore(insertionPoint); addresses.insert({pair.first, synthesizedGep}); } } return addresses; }