blob: 018feb035a4fe9720bd7322e79fe55b82ce18e12 [file] [log] [blame]
Andrew Lenharth4130a4f2005-11-10 01:58:38 +00001//===- Reg2Mem.cpp - Convert registers to allocas -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Andrew Lenharth4130a4f2005-11-10 01:58:38 +00007//
8//===----------------------------------------------------------------------===//
9//
Benjamin Kramerbde91762012-06-02 10:20:22 +000010// This file demotes all registers to memory references. It is intended to be
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000011// the inverse of PromoteMemoryToRegister. By converting to loads, the only
Chris Lattner0ab5e2c2011-04-15 05:18:47 +000012// values live across basic blocks are allocas and loads before phi nodes.
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000013// It is intended that this should make CFG hacking much easier.
14// To make later hacking easier, the entry block is split into two, such that
15// all introduced allocas and nothing else are in the entry block.
16//
17//===----------------------------------------------------------------------===//
18
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/ADT/Statistic.h"
David Blaikie31b98d22018-06-04 21:23:21 +000020#include "llvm/Transforms/Utils/Local.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000021#include "llvm/IR/BasicBlock.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000022#include "llvm/IR/CFG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/Function.h"
24#include "llvm/IR/Instructions.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000027#include "llvm/Pass.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000028#include "llvm/Transforms/Scalar.h"
David Blaikiea373d182018-03-28 17:44:36 +000029#include "llvm/Transforms/Utils.h"
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000030#include <list>
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000031using namespace llvm;
32
Chandler Carruth964daaa2014-04-22 02:55:47 +000033#define DEBUG_TYPE "reg2mem"
34
Anton Korobeynikov7499a3b2007-10-21 23:05:16 +000035STATISTIC(NumRegsDemoted, "Number of registers demoted");
36STATISTIC(NumPhisDemoted, "Number of phi-nodes demoted");
Chris Lattner79a42ac2006-12-19 21:40:18 +000037
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000038namespace {
Chris Lattner2dd09db2009-09-02 06:11:42 +000039 struct RegToMem : public FunctionPass {
Nick Lewyckye7da2d62007-05-06 13:37:16 +000040 static char ID; // Pass identification, replacement for typeid
Owen Anderson6c18d1a2010-10-19 17:21:58 +000041 RegToMem() : FunctionPass(ID) {
42 initializeRegToMemPass(*PassRegistry::getPassRegistry());
43 }
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000044
Craig Topper3e4c6972014-03-05 09:10:37 +000045 void getAnalysisUsage(AnalysisUsage &AU) const override {
Andrew Lenharth71b09bb2005-11-22 21:45:19 +000046 AU.addRequiredID(BreakCriticalEdgesID);
Andrew Lenharth5fc37942005-11-25 16:04:54 +000047 AU.addPreservedID(BreakCriticalEdgesID);
Andrew Lenharth71b09bb2005-11-22 21:45:19 +000048 }
49
Chandler Carruthcdf47882014-03-09 03:16:01 +000050 bool valueEscapes(const Instruction *Inst) const {
51 const BasicBlock *BB = Inst->getParent();
52 for (const User *U : Inst->users()) {
53 const Instruction *UI = cast<Instruction>(U);
54 if (UI->getParent() != BB || isa<PHINode>(UI))
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000055 return true;
Gabor Greifc08e5df2010-04-14 16:48:56 +000056 }
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000057 return false;
58 }
59
Craig Topper3e4c6972014-03-05 09:10:37 +000060 bool runOnFunction(Function &F) override;
Andrew Lenharth4130a4f2005-11-10 01:58:38 +000061 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000062}
Nadav Rotem465834c2012-07-24 10:51:42 +000063
Dan Gohmand78c4002008-05-13 00:00:25 +000064char RegToMem::ID = 0;
Owen Anderson8ac477f2010-10-12 19:48:12 +000065INITIALIZE_PASS_BEGIN(RegToMem, "reg2mem", "Demote all values to stack slots",
Owen Andersondf7a4f22010-10-07 22:25:06 +000066 false, false)
Owen Anderson8ac477f2010-10-12 19:48:12 +000067INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
68INITIALIZE_PASS_END(RegToMem, "reg2mem", "Demote all values to stack slots",
69 false, false)
Chris Lattner09a79dc2009-09-02 06:15:37 +000070
71bool RegToMem::runOnFunction(Function &F) {
Andrew Kaylor50271f72016-05-03 22:32:30 +000072 if (F.isDeclaration() || skipFunction(F))
Chris Lattner09a79dc2009-09-02 06:15:37 +000073 return false;
Nadav Rotem465834c2012-07-24 10:51:42 +000074
Chris Lattner09a79dc2009-09-02 06:15:37 +000075 // Insert all new allocas into entry block.
76 BasicBlock *BBEntry = &F.getEntryBlock();
Ramkumar Ramachandra40c3e032015-01-13 03:46:47 +000077 assert(pred_empty(BBEntry) &&
Chris Lattner09a79dc2009-09-02 06:15:37 +000078 "Entry block to function must not have predecessors!");
Nadav Rotem465834c2012-07-24 10:51:42 +000079
Chris Lattner09a79dc2009-09-02 06:15:37 +000080 // Find first non-alloca instruction and create insertion point. This is
81 // safe if block is well-formed: it always have terminator, otherwise
82 // we'll get and assertion.
83 BasicBlock::iterator I = BBEntry->begin();
84 while (isa<AllocaInst>(I)) ++I;
Nadav Rotem465834c2012-07-24 10:51:42 +000085
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +000086 CastInst *AllocaInsertionPoint = new BitCastInst(
87 Constant::getNullValue(Type::getInt32Ty(F.getContext())),
88 Type::getInt32Ty(F.getContext()), "reg2mem alloca point", &*I);
Nadav Rotem465834c2012-07-24 10:51:42 +000089
Chris Lattner09a79dc2009-09-02 06:15:37 +000090 // Find the escaped instructions. But don't create stack slots for
91 // allocas in entry block.
92 std::list<Instruction*> WorkList;
Benjamin Kramer135f7352016-06-26 12:28:59 +000093 for (BasicBlock &ibb : F)
94 for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie;
95 ++iib) {
Chris Lattner09a79dc2009-09-02 06:15:37 +000096 if (!(isa<AllocaInst>(iib) && iib->getParent() == BBEntry) &&
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +000097 valueEscapes(&*iib)) {
Chris Lattner09a79dc2009-09-02 06:15:37 +000098 WorkList.push_front(&*iib);
99 }
100 }
Nadav Rotem465834c2012-07-24 10:51:42 +0000101
Chris Lattner09a79dc2009-09-02 06:15:37 +0000102 // Demote escaped instructions
103 NumRegsDemoted += WorkList.size();
Benjamin Kramer135f7352016-06-26 12:28:59 +0000104 for (Instruction *ilb : WorkList)
105 DemoteRegToStack(*ilb, false, AllocaInsertionPoint);
Nadav Rotem465834c2012-07-24 10:51:42 +0000106
Chris Lattner09a79dc2009-09-02 06:15:37 +0000107 WorkList.clear();
Nadav Rotem465834c2012-07-24 10:51:42 +0000108
Chris Lattner09a79dc2009-09-02 06:15:37 +0000109 // Find all phi's
Benjamin Kramer135f7352016-06-26 12:28:59 +0000110 for (BasicBlock &ibb : F)
111 for (BasicBlock::iterator iib = ibb.begin(), iie = ibb.end(); iib != iie;
112 ++iib)
Chris Lattner09a79dc2009-09-02 06:15:37 +0000113 if (isa<PHINode>(iib))
114 WorkList.push_front(&*iib);
Nadav Rotem465834c2012-07-24 10:51:42 +0000115
Chris Lattner09a79dc2009-09-02 06:15:37 +0000116 // Demote phi nodes
117 NumPhisDemoted += WorkList.size();
Benjamin Kramer135f7352016-06-26 12:28:59 +0000118 for (Instruction *ilb : WorkList)
119 DemotePHIToStack(cast<PHINode>(ilb), AllocaInsertionPoint);
Nadav Rotem465834c2012-07-24 10:51:42 +0000120
Chris Lattner09a79dc2009-09-02 06:15:37 +0000121 return true;
122}
123
124
Andrew Lenharth4130a4f2005-11-10 01:58:38 +0000125// createDemoteRegisterToMemory - Provide an entry point to create this pass.
Owen Andersona7aed182010-08-06 18:33:48 +0000126char &llvm::DemoteRegisterToMemoryID = RegToMem::ID;
Andrew Lenharth4130a4f2005-11-10 01:58:38 +0000127FunctionPass *llvm::createDemoteRegisterToMemoryPass() {
128 return new RegToMem();
129}