Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: src/IceInst.h

Issue 1311653003: Add UBSAN build option and fix undefined behaviour errors. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Remove x-macros Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// This file declares the Inst class and its target-independent 11 /// This file declares the Inst class and its target-independent
12 /// subclasses, which represent the high-level Vanilla ICE instructions 12 /// subclasses, which represent the high-level Vanilla ICE instructions
13 /// and map roughly 1:1 to LLVM instructions. 13 /// and map roughly 1:1 to LLVM instructions.
14 /// 14 ///
15 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
16 16
17 #ifndef SUBZERO_SRC_ICEINST_H 17 #ifndef SUBZERO_SRC_ICEINST_H
18 #define SUBZERO_SRC_ICEINST_H 18 #define SUBZERO_SRC_ICEINST_H
19 19
20 #include "IceCfg.h" 20 #include "IceCfg.h"
21 #include "IceDefs.h" 21 #include "IceDefs.h"
22 #include "IceInst.def" 22 #include "IceInst.def"
23 #include "IceIntrinsics.h" 23 #include "IceIntrinsics.h"
24 #include "IceTypes.h" 24 #include "IceTypes.h"
25 25
26 // TODO: The Cfg structure, and instructions in particular, need to be 26 // TODO: The Cfg structure, and instructions in particular, need to be
27 // validated for things like valid operand types, valid branch 27 // validated for things like valid operand types, valid branch targets, proper
28 // targets, proper ordering of Phi and non-Phi instructions, etc. 28 // ordering of Phi and non-Phi instructions, etc. Most of the validity
29 // Most of the validity checking will be done in the bitcode reader. 29 // checking will be done in the bitcode reader. We need a list of everything
30 // We need a list of everything that should be validated, and tests 30 // that should be validated, and tests for each.
31 // for each.
32 31
33 namespace Ice { 32 namespace Ice {
34 33
35 /// Base instruction class for ICE. Inst has two subclasses: 34 /// Base instruction class for ICE. Inst has two subclasses: InstHighLevel and
36 /// InstHighLevel and InstTarget. High-level ICE instructions inherit 35 /// InstTarget. High-level ICE instructions inherit from InstHighLevel, and
37 /// from InstHighLevel, and low-level (target-specific) ICE 36 /// low-level (target-specific) ICE instructions inherit from InstTarget.
38 /// instructions inherit from InstTarget.
39 class Inst : public llvm::ilist_node<Inst> { 37 class Inst : public llvm::ilist_node<Inst> {
40 Inst() = delete; 38 Inst() = delete;
41 Inst(const Inst &) = delete; 39 Inst(const Inst &) = delete;
42 Inst &operator=(const Inst &) = delete; 40 Inst &operator=(const Inst &) = delete;
43 41
44 public: 42 public:
45 enum InstKind { 43 enum InstKind {
46 // Arbitrary (alphabetical) order, except put Unreachable first. 44 // Arbitrary (alphabetical) order, except put Unreachable first.
47 Unreachable, 45 Unreachable,
48 Alloca, 46 Alloca,
(...skipping 12 matching lines...) Expand all
61 Select, 59 Select,
62 Store, 60 Store,
63 Switch, 61 Switch,
64 Assign, // not part of LLVM/PNaCl bitcode 62 Assign, // not part of LLVM/PNaCl bitcode
65 BundleLock, // not part of LLVM/PNaCl bitcode 63 BundleLock, // not part of LLVM/PNaCl bitcode
66 BundleUnlock, // not part of LLVM/PNaCl bitcode 64 BundleUnlock, // not part of LLVM/PNaCl bitcode
67 FakeDef, // not part of LLVM/PNaCl bitcode 65 FakeDef, // not part of LLVM/PNaCl bitcode
68 FakeUse, // not part of LLVM/PNaCl bitcode 66 FakeUse, // not part of LLVM/PNaCl bitcode
69 FakeKill, // not part of LLVM/PNaCl bitcode 67 FakeKill, // not part of LLVM/PNaCl bitcode
70 JumpTable, // not part of LLVM/PNaCl bitcode 68 JumpTable, // not part of LLVM/PNaCl bitcode
71 Target // target-specific low-level ICE 69 // Anything >= Target is an InstTarget subclass. Note that the value-spaces
72 // Anything >= Target is an InstTarget subclass. 70 // are shared across targets. To avoid confusion over the definition of
73 // Note that the value-spaces are shared across targets. 71 // shared values, an object specific to one target should never be passed
74 // To avoid confusion over the definition of shared values, 72 // to a different target.
75 // an object specific to one target should never be passed 73 Target,
76 // to a different target. 74 Target_Max = std::numeric_limits<uint8_t>::max(),
77 }; 75 };
78 InstKind getKind() const { return Kind; } 76 InstKind getKind() const { return Kind; }
79 77
80 InstNumberT getNumber() const { return Number; } 78 InstNumberT getNumber() const { return Number; }
81 void renumber(Cfg *Func); 79 void renumber(Cfg *Func);
82 enum { 80 enum {
83 NumberDeleted = -1, 81 NumberDeleted = -1,
84 NumberSentinel = 0, 82 NumberSentinel = 0,
85 NumberInitial = 2, 83 NumberInitial = 2,
86 NumberExtended = NumberInitial - 1 84 NumberExtended = NumberInitial - 1
(...skipping 13 matching lines...) Expand all
100 98
101 SizeT getSrcSize() const { return NumSrcs; } 99 SizeT getSrcSize() const { return NumSrcs; }
102 Operand *getSrc(SizeT I) const { 100 Operand *getSrc(SizeT I) const {
103 assert(I < getSrcSize()); 101 assert(I < getSrcSize());
104 return Srcs[I]; 102 return Srcs[I];
105 } 103 }
106 104
107 bool isLastUse(const Operand *Src) const; 105 bool isLastUse(const Operand *Src) const;
108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); 106 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
109 107
110 /// Returns a list of out-edges corresponding to a terminator 108 /// Returns a list of out-edges corresponding to a terminator instruction,
111 /// instruction, which is the last instruction of the block. 109 /// which is the last instruction of the block. The list must not contain
112 /// The list must not contain duplicates. 110 /// duplicates.
113 virtual NodeList getTerminatorEdges() const { 111 virtual NodeList getTerminatorEdges() const {
114 // All valid terminator instructions override this method. For 112 // All valid terminator instructions override this method. For the default
115 // the default implementation, we assert in case some CfgNode 113 // implementation, we assert in case some CfgNode is constructed without a
116 // is constructed without a terminator instruction at the end. 114 // terminator instruction at the end.
117 llvm_unreachable( 115 llvm_unreachable(
118 "getTerminatorEdges() called on a non-terminator instruction"); 116 "getTerminatorEdges() called on a non-terminator instruction");
119 return NodeList(); 117 return NodeList();
120 } 118 }
121 virtual bool isUnconditionalBranch() const { return false; } 119 virtual bool isUnconditionalBranch() const { return false; }
122 /// If the instruction is a branch-type instruction with OldNode as a 120 /// If the instruction is a branch-type instruction with OldNode as a
123 /// target, repoint it to NewNode and return true, otherwise return 121 /// target, repoint it to NewNode and return true, otherwise return
124 /// false. Repoint all instances of OldNode as a target. 122 /// false. Repoint all instances of OldNode as a target.
125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { 123 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
126 (void)OldNode; 124 (void)OldNode;
127 (void)NewNode; 125 (void)NewNode;
128 return false; 126 return false;
129 } 127 }
130 128
131 virtual bool isSimpleAssign() const { return false; } 129 virtual bool isSimpleAssign() const { return false; }
132 130
133 void livenessLightweight(Cfg *Func, LivenessBV &Live); 131 void livenessLightweight(Cfg *Func, LivenessBV &Live);
134 /// Calculates liveness for this instruction. Returns true if this 132 // Calculates liveness for this instruction. Returns true if this
135 /// instruction is (tentatively) still live and should be retained, 133 /// instruction is (tentatively) still live and should be retained, and false
136 /// and false if this instruction is (tentatively) dead and should be 134 /// if this instruction is (tentatively) dead and should be deleted. The
137 /// deleted. The decision is tentative until the liveness dataflow 135 /// decision is tentative until the liveness dataflow algorithm has converged,
138 /// algorithm has converged, and then a separate pass permanently 136 /// and then a separate pass permanently deletes dead instructions.
139 /// deletes dead instructions.
140 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, 137 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
141 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); 138 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
142 139
143 /// Get the number of native instructions that this instruction 140 /// Get the number of native instructions that this instruction ultimately
144 /// ultimately emits. By default, high-level instructions don't 141 /// emits. By default, high-level instructions don't result in any native
145 /// result in any native instructions, and a target-specific 142 /// instructions, and a target-specific instruction results in a single native
146 /// instruction results in a single native instruction. 143 /// instruction.
147 virtual uint32_t getEmitInstCount() const { return 0; } 144 virtual uint32_t getEmitInstCount() const { return 0; }
148 // TODO(stichnot): Change Inst back to abstract once the g++ build 145 // TODO(stichnot): Change Inst back to abstract once the g++ build
149 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ 146 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
150 // because the resize(size_t, Ice::Inst) method is incorrectly 147 // because the resize(size_t, Ice::Inst) method is incorrectly
151 // declared and thus doesn't allow the abstract class Ice::Inst. 148 // declared and thus doesn't allow the abstract class Ice::Inst.
152 // The method should be declared resize(size_t, const Ice::Inst &). 149 // The method should be declared resize(size_t, const Ice::Inst &).
153 // virtual void emit(const Cfg *Func) const = 0; 150 // virtual void emit(const Cfg *Func) const = 0;
154 // virtual void emitIAS(const Cfg *Func) const = 0; 151 // virtual void emitIAS(const Cfg *Func) const = 0;
155 virtual void emit(const Cfg *) const { 152 virtual void emit(const Cfg *) const {
156 llvm_unreachable("emit on abstract class"); 153 llvm_unreachable("emit on abstract class");
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 950
954 public: 951 public:
955 uint32_t getEmitInstCount() const override { return 1; } 952 uint32_t getEmitInstCount() const override { return 1; }
956 void dump(const Cfg *Func) const override; 953 void dump(const Cfg *Func) const override;
957 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } 954 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
958 955
959 protected: 956 protected:
960 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 957 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
961 : Inst(Func, Kind, MaxSrcs, Dest) { 958 : Inst(Func, Kind, MaxSrcs, Dest) {
962 assert(Kind >= Target); 959 assert(Kind >= Target);
960 assert(Kind <= Target_Max);
963 } 961 }
964 }; 962 };
965 963
966 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); 964 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
967 965
968 } // end of namespace Ice 966 } // end of namespace Ice
969 967
970 namespace llvm { 968 namespace llvm {
971 969
972 /// Override the default ilist traits so that Inst's private ctor and 970 /// Override the default ilist traits so that Inst's private ctor and
973 /// deleted dtor aren't invoked. 971 /// deleted dtor aren't invoked.
974 template <> 972 template <>
975 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { 973 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
976 Ice::Inst *createSentinel() const { 974 Ice::Inst *createSentinel() const {
977 return static_cast<Ice::Inst *>(&Sentinel); 975 return static_cast<Ice::Inst *>(&Sentinel);
978 } 976 }
979 static void destroySentinel(Ice::Inst *) {} 977 static void destroySentinel(Ice::Inst *) {}
980 Ice::Inst *provideInitialHead() const { return createSentinel(); } 978 Ice::Inst *provideInitialHead() const { return createSentinel(); }
981 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); } 979 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
982 static void noteHead(Ice::Inst *, Ice::Inst *) {} 980 static void noteHead(Ice::Inst *, Ice::Inst *) {}
983 void deleteNode(Ice::Inst *) {} 981 void deleteNode(Ice::Inst *) {}
984 982
985 private: 983 private:
986 mutable ilist_half_node<Ice::Inst> Sentinel; 984 mutable ilist_half_node<Ice::Inst> Sentinel;
987 }; 985 };
988 986
989 } // end of namespace llvm 987 } // end of namespace llvm
990 988
991 #endif // SUBZERO_SRC_ICEINST_H 989 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW
« no previous file with comments | « src/IceAssembler.h ('k') | src/IceOperand.h » ('j') | src/IceOperand.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698