blob: cf456af0365130f07dce29621efd81fafd32fca5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Intel, Pavel A. Ozhdikhin
*
*/
#ifndef _MEMORY_OPT_H
#define _MEMORY_OPT_H
#include <iostream>
#include "open/types.h"
#include "Opcode.h"
#include "Stl.h"
#include <utility>
namespace Jitrino {
class IRManager;
class MemoryManager;
class InequalityGraph;
class DominatorNode;
class Dominator;
class DomFrontier;
class Node;
class Opnd;
class CSEHashTable;
class Type;
class LoopTree;
class AliasManager;
class InstMemBehavior;
class AliasAnalyzer;
class AliasDefSites;
class AliasRep;
class VarDefSites;
class MemPhiSites;
class AliasRenameMap;
class MemUseMap;
struct MemoptFlags;
class MemoryOpt {
IRManager& irManager;
ControlFlowGraph& fg;
MemoryManager &mm;
DominatorTree& dominators;
DomFrontier &df;
LoopTree *loopTree;
AliasManager *aliasManager;
typedef StlHashMap<Inst *, InstMemBehavior *> Inst2MemBehavior;
Inst2MemBehavior *instDoesWhat;
AliasDefSites *aliasDefSites;
MemPhiSites *memPhiSites;
AliasRenameMap *renameMap;
typedef StlVectorSet<Inst *> UsesSet;
typedef StlHashMap<Inst *, UsesSet *> Def2UsesMap;
typedef StlVectorSet<Inst *> DefsSet;
typedef StlHashMap<Inst *, DefsSet *> Use2DefsMap;
Use2DefsMap memUseDefs;
Def2UsesMap memDefUses;
InstMemBehavior *getOrCreateInstEffect(Inst *i);
InstMemBehavior *getInstEffect(Inst *i); // 0 if none
public:
enum Model {
Model_Strict, // mark all memory operations unmovable,
// unCSEable
Model_ReadsKill, // each read acts like it is immediately
// followed by a write for the purposes of
// computing dependences below
Model_CseFinal, // allows CSE of all final fields
Model_Default
};
enum Synch {
Synch_Fence, // monitorEnter/monitorExit acts like a
// read/write of ALL
Synch_Moveable, // allow load/store movement into lock regions
// to facilitate fence merging in case of
// eliminable lock
Synch_OnlyLock, // escape analysis can just remove locks,
// versus turning them into fence operations
Synch_OneThread, // turn all lock-type operations into
// unsynchronized operations
Synch_Default
};
private:
MemoptFlags& flags;
public:
static void readFlags(Action* argSource, MemoptFlags* flags);
static void showFlags(std::ostream& os);
MemoryOpt(IRManager &irManager0,
MemoryManager& memManager,
DominatorTree& dom0,
DomFrontier& df0,
LoopTree *loopTree,
AliasAnalyzer *aa0);
~MemoryOpt();
void runPass();
bool hasSameReachingDefs(Inst *i1, Inst *i2);
bool hasDefReachesUse(Inst *def, Inst *use);
// update maps with transitive closure of i1, then remove i1 from def-use
void eliminateRedStores();
void doSyncOpt();
private:
// renaming phase for SSA construction
void initMemoryOperations();
void insertMemPhi();
void createUsesMap();
void createMemPhiInst(const AliasRep &, Node *n);
void insertPhiFor(const AliasRep &theRep, VarDefSites* defSites,
StlList<VarDefSites *> &ancestorSites);
friend class MemoryOptInitWalker;
friend class MemoryRenameWalker;
friend class MemoryDebugWalker;
friend class MemoryRedStoreWalker;
friend class MemorySyncOptWalker;
// methods to note memory effects of an instruction
void effectAnyGlobal(Node *n, Inst *i); // R/W anything that escapes or is global
void effectWriteVtable(Node *n, Inst *i, Opnd *opnd);
void effectReadVtable(Node *n, Inst *i, Opnd *opnd);
void effectReadMethodPtr(Node *n, Inst *i, Opnd *obj, MethodDesc *desc);
void effectReadMethodPtr(Node *n, Inst *i, MethodDesc *desc);
void effectReadFunPtr(Node *n, Inst *i, Opnd *funptr);
void effectInit(Node *n, Inst *i); // initial state, everything defined
void effectExit(Node *n, Inst *i);
void effectEntry(Node *n, Inst *i); // just globals overwritten
void effectRead(Node *n, Inst *i, Opnd *addr);
void effectWrite(Node *n, Inst *i, Opnd *addr);
void effectReadClassVtable(Node *n, Inst *i, NamedType *t);
void effectWriteArrayLength(Node *n, Inst *i, Opnd *opnd);
void effectReadArrayLength(Node *n, Inst *i, Opnd *opnd);
void effectReadArrayElements(Node *n, Inst *i, Opnd *arrayop,
Opnd *offsetop, Opnd *length);
void effectWriteArrayElements(Node *n, Inst *i, Opnd *arrayop,
Opnd *offsetop, Opnd *length);
// creates an object/array, returned in opnd:
// writes array length, etc.
void effectNew(Node *n, Inst *i, Opnd *dstop);
// make sure object's vtable are visible to others before publishing this
void effectReleaseObject(Node *n, Inst *i, Opnd *obj);
// make sure object's vtable is available to all
void effectInitType(Node *n, Inst *i, NamedType *type);
// mark end of initializer when finalizers should stay constant:
void effectFinishObject(Node *n, Inst *i, Opnd *obj);
void effectFinishType(Node *n, Inst *i, NamedType *type);
// can commute with any ops, but not be added/removed:
void effectIncCounter(Node *n, Inst *i);
// object may be 0 if lock has been removed
void effectMonitorEnter(Node *n, Inst *i, Opnd *object);
void effectMonitorExit(Node *n, Inst *i, Opnd *object);
// just increments the lock on object, no acq/rel
void effectIncRecCount(Node *n, Inst *i, Opnd *object);
// lock type methods
void effectTypeMonitorEnter(Node *n, Inst *i, Type *type);
void effectTypeMonitorExit(Node *n, Inst *i, Type *type);
private:
// implementation
void addDefToInstruction(Node *n, Inst *i, const AliasRep &thisMem);
void addUseToInstruction(Node *n, Inst *i, const AliasRep &thisMem);
void addReleaseToInstruction(Node *n, Inst *i);
void addAcquireToInstruction(Node *n, Inst *i);
void addMemUseDef(Inst *use, Inst *def);
void addMemUseDefs(Inst *use, DefsSet &defs);
public:
void remMemInst(Inst *inst); // notify MemoryOpt that we're removing this inst
void replaceMemInst(Inst *oldI, Inst *newI); // substitute dep info
};
struct MemoptFlags {
enum MemoryOpt::Model model;
enum MemoryOpt::Synch synch;
bool debug;
bool verbose;
bool redstore;
bool syncopt;
bool do_redstore;
};
} //namespace Jitrino
#endif // _MEMORY_OPT_H