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

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: Neater way to set Target_Max 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 "IceTargetKinds.def"
24 #include "IceTypes.h" 25 #include "IceTypes.h"
25 26
26 // TODO: The Cfg structure, and instructions in particular, need to be 27 // TODO: The Cfg structure, and instructions in particular, need to be
27 // validated for things like valid operand types, valid branch 28 // validated for things like valid operand types, valid branch targets, proper
28 // targets, proper ordering of Phi and non-Phi instructions, etc. 29 // 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. 30 // 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 31 // that should be validated, and tests for each.
31 // for each.
32 32
33 namespace Ice { 33 namespace Ice {
34 34
35 /// Base instruction class for ICE. Inst has two subclasses: 35 /// Base instruction class for ICE. Inst has two subclasses: InstHighLevel and
36 /// InstHighLevel and InstTarget. High-level ICE instructions inherit 36 /// InstTarget. High-level ICE instructions inherit from InstHighLevel, and
37 /// from InstHighLevel, and low-level (target-specific) ICE 37 /// low-level (target-specific) ICE instructions inherit from InstTarget.
38 /// instructions inherit from InstTarget.
39 class Inst : public llvm::ilist_node<Inst> { 38 class Inst : public llvm::ilist_node<Inst> {
40 Inst() = delete; 39 Inst() = delete;
41 Inst(const Inst &) = delete; 40 Inst(const Inst &) = delete;
42 Inst &operator=(const Inst &) = delete; 41 Inst &operator=(const Inst &) = delete;
43 42
44 public: 43 public:
45 enum InstKind { 44 enum InstKind {
46 // Arbitrary (alphabetical) order, except put Unreachable first. 45 // Arbitrary (alphabetical) order, except put Unreachable first.
47 Unreachable, 46 Unreachable,
48 Alloca, 47 Alloca,
(...skipping 12 matching lines...) Expand all
61 Select, 60 Select,
62 Store, 61 Store,
63 Switch, 62 Switch,
64 Assign, // not part of LLVM/PNaCl bitcode 63 Assign, // not part of LLVM/PNaCl bitcode
65 BundleLock, // not part of LLVM/PNaCl bitcode 64 BundleLock, // not part of LLVM/PNaCl bitcode
66 BundleUnlock, // not part of LLVM/PNaCl bitcode 65 BundleUnlock, // not part of LLVM/PNaCl bitcode
67 FakeDef, // not part of LLVM/PNaCl bitcode 66 FakeDef, // not part of LLVM/PNaCl bitcode
68 FakeUse, // not part of LLVM/PNaCl bitcode 67 FakeUse, // not part of LLVM/PNaCl bitcode
69 FakeKill, // not part of LLVM/PNaCl bitcode 68 FakeKill, // not part of LLVM/PNaCl bitcode
70 JumpTable, // not part of LLVM/PNaCl bitcode 69 JumpTable, // not part of LLVM/PNaCl bitcode
71 Target // target-specific low-level ICE 70 // target-specific low-level ICE Anything >= Target is an InstTarget
Jim Stichnoth 2015/09/04 21:32:48 probably delete the "target-specific low-level ICE
ascull 2015/09/05 00:00:48 Done.
72 // Anything >= Target is an InstTarget subclass. 71 // subclass. Note that the value-spaces are shared across targets. To
73 // Note that the value-spaces are shared across targets. 72 // avoid confusion over the definition of shared values, an object specific
74 // To avoid confusion over the definition of shared values, 73 // to one target should never be passed to a different target.
75 // an object specific to one target should never be passed 74 #define X(n) Target##n,
76 // to a different target. 75 TARGETKINDS_INSTS_TABLE
Jim Stichnoth 2015/09/04 21:32:49 IIRC, you are solving the problem by defining Targ
ascull 2015/09/05 00:00:48 I'm not sure I see what you mean here. You need to
Jim Stichnoth 2015/09/05 01:03:22 I believe the UB comes from trying to represent an
ascull 2015/09/08 17:29:26 Done.
76 #undef X
77 }; 77 };
78 InstKind getKind() const { return Kind; } 78 InstKind getKind() const { return Kind; }
79 79
80 InstNumberT getNumber() const { return Number; } 80 InstNumberT getNumber() const { return Number; }
81 void renumber(Cfg *Func); 81 void renumber(Cfg *Func);
82 enum { 82 enum {
83 NumberDeleted = -1, 83 NumberDeleted = -1,
84 NumberSentinel = 0, 84 NumberSentinel = 0,
85 NumberInitial = 2, 85 NumberInitial = 2,
86 NumberExtended = NumberInitial - 1 86 NumberExtended = NumberInitial - 1
(...skipping 13 matching lines...) Expand all
100 100
101 SizeT getSrcSize() const { return NumSrcs; } 101 SizeT getSrcSize() const { return NumSrcs; }
102 Operand *getSrc(SizeT I) const { 102 Operand *getSrc(SizeT I) const {
103 assert(I < getSrcSize()); 103 assert(I < getSrcSize());
104 return Srcs[I]; 104 return Srcs[I];
105 } 105 }
106 106
107 bool isLastUse(const Operand *Src) const; 107 bool isLastUse(const Operand *Src) const;
108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); 108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
109 109
110 /// Returns a list of out-edges corresponding to a terminator 110 /// Returns a list of out-edges corresponding to a terminator instruction,
111 /// instruction, which is the last instruction of the block. 111 /// which is the last instruction of the block. The list must not contain
112 /// The list must not contain duplicates. 112 /// duplicates.
113 virtual NodeList getTerminatorEdges() const { 113 virtual NodeList getTerminatorEdges() const {
114 // All valid terminator instructions override this method. For 114 // All valid terminator instructions override this method. For the default
115 // the default implementation, we assert in case some CfgNode 115 // implementation, we assert in case some CfgNode is constructed without a
116 // is constructed without a terminator instruction at the end. 116 // terminator instruction at the end.
117 llvm_unreachable( 117 llvm_unreachable(
118 "getTerminatorEdges() called on a non-terminator instruction"); 118 "getTerminatorEdges() called on a non-terminator instruction");
119 return NodeList(); 119 return NodeList();
120 } 120 }
121 virtual bool isUnconditionalBranch() const { return false; } 121 virtual bool isUnconditionalBranch() const { return false; }
122 /// If the instruction is a branch-type instruction with OldNode as a 122 /// If the instruction is a branch-type instruction with OldNode as a
123 /// target, repoint it to NewNode and return true, otherwise return 123 /// target, repoint it to NewNode and return true, otherwise return
124 /// false. Repoint all instances of OldNode as a target. 124 /// false. Repoint all instances of OldNode as a target.
125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { 125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
126 (void)OldNode; 126 (void)OldNode;
127 (void)NewNode; 127 (void)NewNode;
128 return false; 128 return false;
129 } 129 }
130 130
131 virtual bool isSimpleAssign() const { return false; } 131 virtual bool isSimpleAssign() const { return false; }
132 132
133 void livenessLightweight(Cfg *Func, LivenessBV &Live); 133 void livenessLightweight(Cfg *Func, LivenessBV &Live);
134 /// Calculates liveness for this instruction. Returns true if this 134 // Calculates liveness for this instruction. Returns true if this
135 /// instruction is (tentatively) still live and should be retained, 135 /// instruction is (tentatively) still live and should be retained, and false
136 /// and false if this instruction is (tentatively) dead and should be 136 /// if this instruction is (tentatively) dead and should be deleted. The
137 /// deleted. The decision is tentative until the liveness dataflow 137 /// decision is tentative until the liveness dataflow algorithm has converged,
138 /// algorithm has converged, and then a separate pass permanently 138 /// and then a separate pass permanently deletes dead instructions.
139 /// deletes dead instructions.
140 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, 139 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
141 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); 140 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
142 141
143 /// Get the number of native instructions that this instruction 142 /// Get the number of native instructions that this instruction ultimately
144 /// ultimately emits. By default, high-level instructions don't 143 /// emits. By default, high-level instructions don't result in any native
145 /// result in any native instructions, and a target-specific 144 /// instructions, and a target-specific instruction results in a single native
146 /// instruction results in a single native instruction. 145 /// instruction.
147 virtual uint32_t getEmitInstCount() const { return 0; } 146 virtual uint32_t getEmitInstCount() const { return 0; }
148 // TODO(stichnot): Change Inst back to abstract once the g++ build 147 // TODO(stichnot): Change Inst back to abstract once the g++ build
149 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ 148 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
150 // because the resize(size_t, Ice::Inst) method is incorrectly 149 // because the resize(size_t, Ice::Inst) method is incorrectly
151 // declared and thus doesn't allow the abstract class Ice::Inst. 150 // declared and thus doesn't allow the abstract class Ice::Inst.
152 // The method should be declared resize(size_t, const Ice::Inst &). 151 // The method should be declared resize(size_t, const Ice::Inst &).
153 // virtual void emit(const Cfg *Func) const = 0; 152 // virtual void emit(const Cfg *Func) const = 0;
154 // virtual void emitIAS(const Cfg *Func) const = 0; 153 // virtual void emitIAS(const Cfg *Func) const = 0;
155 virtual void emit(const Cfg *) const { 154 virtual void emit(const Cfg *) const {
156 llvm_unreachable("emit on abstract class"); 155 llvm_unreachable("emit on abstract class");
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 /// The Target instruction is the base class for all target-specific 946 /// The Target instruction is the base class for all target-specific
948 /// instructions. 947 /// instructions.
949 class InstTarget : public Inst { 948 class InstTarget : public Inst {
950 InstTarget() = delete; 949 InstTarget() = delete;
951 InstTarget(const InstTarget &) = delete; 950 InstTarget(const InstTarget &) = delete;
952 InstTarget &operator=(const InstTarget &) = delete; 951 InstTarget &operator=(const InstTarget &) = delete;
953 952
954 public: 953 public:
955 uint32_t getEmitInstCount() const override { return 1; } 954 uint32_t getEmitInstCount() const override { return 1; }
956 void dump(const Cfg *Func) const override; 955 void dump(const Cfg *Func) const override;
957 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } 956 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target0; }
958 957
959 protected: 958 protected:
960 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 959 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
961 : Inst(Func, Kind, MaxSrcs, Dest) { 960 : Inst(Func, Kind, MaxSrcs, Dest) {
962 assert(Kind >= Target); 961 assert(Kind >= Target0);
963 } 962 }
964 }; 963 };
965 964
966 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); 965 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
967 966
968 } // end of namespace Ice 967 } // end of namespace Ice
969 968
970 namespace llvm { 969 namespace llvm {
971 970
972 /// Override the default ilist traits so that Inst's private ctor and 971 /// Override the default ilist traits so that Inst's private ctor and
973 /// deleted dtor aren't invoked. 972 /// deleted dtor aren't invoked.
974 template <> 973 template <>
975 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { 974 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
976 Ice::Inst *createSentinel() const { 975 Ice::Inst *createSentinel() const {
977 return static_cast<Ice::Inst *>(&Sentinel); 976 return static_cast<Ice::Inst *>(&Sentinel);
978 } 977 }
979 static void destroySentinel(Ice::Inst *) {} 978 static void destroySentinel(Ice::Inst *) {}
980 Ice::Inst *provideInitialHead() const { return createSentinel(); } 979 Ice::Inst *provideInitialHead() const { return createSentinel(); }
981 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); } 980 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
982 static void noteHead(Ice::Inst *, Ice::Inst *) {} 981 static void noteHead(Ice::Inst *, Ice::Inst *) {}
983 void deleteNode(Ice::Inst *) {} 982 void deleteNode(Ice::Inst *) {}
984 983
985 private: 984 private:
986 mutable ilist_half_node<Ice::Inst> Sentinel; 985 mutable ilist_half_node<Ice::Inst> Sentinel;
987 }; 986 };
988 987
989 } // end of namespace llvm 988 } // end of namespace llvm
990 989
991 #endif // SUBZERO_SRC_ICEINST_H 990 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698