blob: 3296322e00d5fb6ec43d254e9da7c797897d1d8f [file] [log] [blame]
Andrew Lenharth4130a4f2005-11-10 01:58:38 +00001//===- Reg2Mem.cpp - Convert registers to allocas -------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Lenharth4130a4f2005-11-10 01:58:38 +00006//
7//===----------------------------------------------------------------------===//
8//
Benjamin Kramerbde91762012-06-02 10:20:22 +00009// This file demotes all registers to memory references. It is intended to be
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000010// the inverse of PromoteMemoryToRegister. By converting to loads, the only
Chris Lattner0ab5e2c2011-04-15 05:18:47 +000011// values live across basic blocks are allocas and loads before phi nodes.
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000012// It is intended that this should make CFG hacking much easier.
13// To make later hacking easier, the entry block is split into two, such that
14// all introduced allocas and nothing else are in the entry block.
15//
16//===----------------------------------------------------------------------===//
17
Chandler Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/ADT/Statistic.h"
David Blaikie31b98d22018-06-04 21:23:21 +000019#include "llvm/Transforms/Utils/Local.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/BasicBlock.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000021#include "llvm/IR/CFG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/Function.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/IR/LLVMContext.h"
25#include "llvm/IR/Module.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000026#include "llvm/Pass.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000027#include "llvm/Transforms/Scalar.h"
David Blaikiea373d182018-03-28 17:44:36 +000028#include "llvm/Transforms/Utils.h"
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000029#include <list>
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000030using namespace llvm;
31
Chandler Carruth964daaa2014-04-22 02:55:47 +000032#define DEBUG_TYPE "reg2mem"
33
Anton Korobeynikov7499a3b2007-10-21 23:05:16 +000034STATISTIC(NumRegsDemoted, "Number of registers demoted");
35STATISTIC(NumPhisDemoted, "Number of phi-nodes demoted");
Chris Lattner79a42ac2006-12-19 21:40:18 +000036
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000037namespace {
Chris Lattner2dd09db2009-09-02 06:11:42 +000038 struct RegToMem : public FunctionPass {
Nick Lewyckye7da2d62007-05-06 13:37:16 +000039 static char ID; // Pass identification, replacement for typeid
Owen Anderson6c18d1a2010-10-19 17:21:58 +000040 RegToMem() : FunctionPass(ID) {
41 initializeRegToMemPass(*PassRegistry::getPassRegistry());
42 }
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000043
Craig Topper3e4c6972014-03-05 09:10:37 +000044 void getAnalysisUsage(AnalysisUsage &AU) const override {
Andrew Lenharth71b09bb2005-11-22 21:45:19 +000045 AU.addRequiredID(BreakCriticalEdgesID);
Andrew Lenharth5fc37942005-11-25 16:04:54 +000046 AU.addPreservedID(BreakCriticalEdgesID);
Andrew Lenharth71b09bb2005-11-22 21:45:19 +000047 }
48
Chandler Carruthcdf47882014-03-09 03:16:01 +000049 bool valueEscapes(const Instruction *Inst) const {
50 const BasicBlock *BB = Inst->getParent();
51 for (const User *U : Inst->users()) {
52 const Instruction *UI = cast<Instruction>(U);
53 if (UI->getParent() != BB || isa<PHINode>(UI))
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000054 return true;
Gabor Greifc08e5df2010-04-14 16:48:56 +000055 }
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000056 return false;
57 }
58
Craig Topper3e4c6972014-03-05 09:10:37 +000059 bool runOnFunction(Function &F) override;
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000060 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000061}
Nadav Rotem465834c2012-07-24 10:51:42 +000062
Dan Gohmand78c4002008-05-13 00:00:25 +000063char RegToMem::ID = 0;
Owen Anderson8ac477f2010-10-12 19:48:12 +000064INITIALIZE_PASS_BEGIN(RegToMem, "reg2mem", "Demote all values to stack slots",
Owen Andersondf7a4f22010-10-07 22:25:06 +000065 false, false)
Owen Anderson8ac477f2010-10-12 19:48:12 +000066INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
67INITIALIZE_PASS_END(RegToMem, "reg2mem", "Demote all values to stack slots",
68 false, false)
Chris Lattner09a79dc2009-09-02 06:15:37 +000069
70bool RegToMem::runOnFunction(Function &F) {
Andrew Kaylor50271f72016-05-03 22:32:30 +000071 if (F.isDeclaration() || skipFunction(F))
Chris Lattner09a79dc2009-09-02 06:15:37 +000072 return false;
Nadav Rotem465834c2012-07-24 10:51:42 +000073
Chris Lattner09a79dc2009-09-02 06:15:37 +000074 // Insert all new allocas into entry block.
75 BasicBlock *BBEntry = &F.getEntryBlock();
Ramkumar Ramachandra40c3e032015-01-13 03:46:47 +000076 assert(pred_empty(BBEntry) &&
Chris Lattner09a79dc2009-09-02 06:15:37 +000077 "Entry block to function must not have predecessors!");
Nadav Rotem465834c2012-07-24 10:51:42 +000078
Chris Lattner09a79dc2009-09-02 06:15:37 +000079 // Find first non-alloca instruction and create insertion point. This is
80 // safe if block is well-formed: it always have terminator, otherwise
81 // we'll get and assertion.
82 BasicBlock::iterator I = BBEntry->begin();
83 while (isa<AllocaInst>(I)) ++I;
Nadav Rotem465834c2012-07-24 10:51:42 +000084
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +000085 CastInst *AllocaInsertionPoint = new BitCastInst(
86 Constant::getNullValue(Type::getInt32Ty(F.getContext())),
87 Type::getInt32Ty(F.getContext()), "reg2mem alloca point", &*I);
Nadav Rotem465834c2012-07-24 10:51:42 +000088
Chris Lattner09a79dc2009-09-02 06:15:37 +000089 // Find the escaped instructions. But don't create stack slots for
90 // allocas in entry block.
91 std::list<Instruction*> WorkList;
Benjamin Kramer135f7352016-06-26 12:28:59 +000092 for (BasicBlock &ibb : F)
93 for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie;
94 ++iib) {
Chris Lattner09a79dc2009-09-02 06:15:37 +000095 if (!(isa<AllocaInst>(iib) && iib->getParent() == BBEntry) &&
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +000096 valueEscapes(&*iib)) {
Chris Lattner09a79dc2009-09-02 06:15:37 +000097 WorkList.push_front(&*iib);
98 }
99 }
Nadav Rotem465834c2012-07-24 10:51:42 +0000100
Chris Lattner09a79dc2009-09-02 06:15:37 +0000101 // Demote escaped instructions
102 NumRegsDemoted += WorkList.size();
Benjamin Kramer135f7352016-06-26 12:28:59 +0000103 for (Instruction *ilb : WorkList)
104 DemoteRegToStack(*ilb, false, AllocaInsertionPoint);
Nadav Rotem465834c2012-07-24 10:51:42 +0000105
Chris Lattner09a79dc2009-09-02 06:15:37 +0000106 WorkList.clear();
Nadav Rotem465834c2012-07-24 10:51:42 +0000107
Chris Lattner09a79dc2009-09-02 06:15:37 +0000108 // Find all phi's
Benjamin Kramer135f7352016-06-26 12:28:59 +0000109 for (BasicBlock &ibb : F)
110 for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie;
111 ++iib)
Chris Lattner09a79dc2009-09-02 06:15:37 +0000112 if (isa<PHINode>(iib))
113 WorkList.push_front(&*iib);
Nadav Rotem465834c2012-07-24 10:51:42 +0000114
Chris Lattner09a79dc2009-09-02 06:15:37 +0000115 // Demote phi nodes
116 NumPhisDemoted += WorkList.size();
Benjamin Kramer135f7352016-06-26 12:28:59 +0000117 for (Instruction *ilb : WorkList)
118 DemotePHIToStack(cast<PHINode>(ilb), AllocaInsertionPoint);
Nadav Rotem465834c2012-07-24 10:51:42 +0000119
Chris Lattner09a79dc2009-09-02 06:15:37 +0000120 return true;
121}
122
123
Andrew Lenharth4130a4f2005-11-10 01:58:38 +0000124// createDemoteRegisterToMemory - Provide an entry point to create this pass.
Owen Andersona7aed182010-08-06 18:33:48 +0000125char &llvm::DemoteRegisterToMemoryID = RegToMem::ID;
Andrew Lenharth4130a4f2005-11-10 01:58:38 +0000126FunctionPass *llvm::createDemoteRegisterToMemoryPass() {
127 return new RegToMem();
128}