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

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: Fix after native_client pull 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
« no previous file with comments | « src/IceConverter.cpp ('k') | src/IceOperand.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 };
76 static_assert(Target <= Target_Max, "Must not be above max.");
78 InstKind getKind() const { return Kind; } 77 InstKind getKind() const { return Kind; }
79 78
80 InstNumberT getNumber() const { return Number; } 79 InstNumberT getNumber() const { return Number; }
81 void renumber(Cfg *Func); 80 void renumber(Cfg *Func);
82 enum { 81 enum {
83 NumberDeleted = -1, 82 NumberDeleted = -1,
84 NumberSentinel = 0, 83 NumberSentinel = 0,
85 NumberInitial = 2, 84 NumberInitial = 2,
86 NumberExtended = NumberInitial - 1 85 NumberExtended = NumberInitial - 1
87 }; 86 };
(...skipping 12 matching lines...) Expand all
100 99
101 SizeT getSrcSize() const { return NumSrcs; } 100 SizeT getSrcSize() const { return NumSrcs; }
102 Operand *getSrc(SizeT I) const { 101 Operand *getSrc(SizeT I) const {
103 assert(I < getSrcSize()); 102 assert(I < getSrcSize());
104 return Srcs[I]; 103 return Srcs[I];
105 } 104 }
106 105
107 bool isLastUse(const Operand *Src) const; 106 bool isLastUse(const Operand *Src) const;
108 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn); 107 void spliceLivenessInfo(Inst *OrigInst, Inst *SpliceAssn);
109 108
110 /// Returns a list of out-edges corresponding to a terminator 109 /// Returns a list of out-edges corresponding to a terminator instruction,
111 /// instruction, which is the last instruction of the block. 110 /// which is the last instruction of the block. The list must not contain
112 /// The list must not contain duplicates. 111 /// duplicates.
113 virtual NodeList getTerminatorEdges() const { 112 virtual NodeList getTerminatorEdges() const {
114 // All valid terminator instructions override this method. For 113 // All valid terminator instructions override this method. For the default
115 // the default implementation, we assert in case some CfgNode 114 // implementation, we assert in case some CfgNode is constructed without a
116 // is constructed without a terminator instruction at the end. 115 // terminator instruction at the end.
117 llvm_unreachable( 116 llvm_unreachable(
118 "getTerminatorEdges() called on a non-terminator instruction"); 117 "getTerminatorEdges() called on a non-terminator instruction");
119 return NodeList(); 118 return NodeList();
120 } 119 }
121 virtual bool isUnconditionalBranch() const { return false; } 120 virtual bool isUnconditionalBranch() const { return false; }
122 /// If the instruction is a branch-type instruction with OldNode as a 121 /// If the instruction is a branch-type instruction with OldNode as a
123 /// target, repoint it to NewNode and return true, otherwise return 122 /// target, repoint it to NewNode and return true, otherwise return
124 /// false. Repoint all instances of OldNode as a target. 123 /// false. Repoint all instances of OldNode as a target.
125 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) { 124 virtual bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
126 (void)OldNode; 125 (void)OldNode;
127 (void)NewNode; 126 (void)NewNode;
128 return false; 127 return false;
129 } 128 }
130 129
131 virtual bool isSimpleAssign() const { return false; } 130 virtual bool isSimpleAssign() const { return false; }
132 131
133 void livenessLightweight(Cfg *Func, LivenessBV &Live); 132 void livenessLightweight(Cfg *Func, LivenessBV &Live);
134 /// Calculates liveness for this instruction. Returns true if this 133 // Calculates liveness for this instruction. Returns true if this
135 /// instruction is (tentatively) still live and should be retained, 134 /// instruction is (tentatively) still live and should be retained, and false
136 /// and false if this instruction is (tentatively) dead and should be 135 /// if this instruction is (tentatively) dead and should be deleted. The
137 /// deleted. The decision is tentative until the liveness dataflow 136 /// decision is tentative until the liveness dataflow algorithm has converged,
138 /// algorithm has converged, and then a separate pass permanently 137 /// and then a separate pass permanently deletes dead instructions.
139 /// deletes dead instructions.
140 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness, 138 bool liveness(InstNumberT InstNumber, LivenessBV &Live, Liveness *Liveness,
141 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd); 139 LiveBeginEndMap *LiveBegin, LiveBeginEndMap *LiveEnd);
142 140
143 /// Get the number of native instructions that this instruction 141 /// Get the number of native instructions that this instruction ultimately
144 /// ultimately emits. By default, high-level instructions don't 142 /// emits. By default, high-level instructions don't result in any native
145 /// result in any native instructions, and a target-specific 143 /// instructions, and a target-specific instruction results in a single native
146 /// instruction results in a single native instruction. 144 /// instruction.
147 virtual uint32_t getEmitInstCount() const { return 0; } 145 virtual uint32_t getEmitInstCount() const { return 0; }
148 // TODO(stichnot): Change Inst back to abstract once the g++ build 146 // TODO(stichnot): Change Inst back to abstract once the g++ build
149 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++ 147 // issue is fixed. llvm::ilist<Ice::Inst> doesn't work under g++
150 // because the resize(size_t, Ice::Inst) method is incorrectly 148 // because the resize(size_t, Ice::Inst) method is incorrectly
151 // declared and thus doesn't allow the abstract class Ice::Inst. 149 // declared and thus doesn't allow the abstract class Ice::Inst.
152 // The method should be declared resize(size_t, const Ice::Inst &). 150 // The method should be declared resize(size_t, const Ice::Inst &).
153 // virtual void emit(const Cfg *Func) const = 0; 151 // virtual void emit(const Cfg *Func) const = 0;
154 // virtual void emitIAS(const Cfg *Func) const = 0; 152 // virtual void emitIAS(const Cfg *Func) const = 0;
155 virtual void emit(const Cfg *) const { 153 virtual void emit(const Cfg *) const {
156 llvm_unreachable("emit on abstract class"); 154 llvm_unreachable("emit on abstract class");
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 951
954 public: 952 public:
955 uint32_t getEmitInstCount() const override { return 1; } 953 uint32_t getEmitInstCount() const override { return 1; }
956 void dump(const Cfg *Func) const override; 954 void dump(const Cfg *Func) const override;
957 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } 955 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
958 956
959 protected: 957 protected:
960 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 958 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
961 : Inst(Func, Kind, MaxSrcs, Dest) { 959 : Inst(Func, Kind, MaxSrcs, Dest) {
962 assert(Kind >= Target); 960 assert(Kind >= Target);
961 assert(Kind <= Target_Max);
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
« no previous file with comments | « src/IceConverter.cpp ('k') | src/IceOperand.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698