@@ -141,6 +141,36 @@ void CodeGenFunction::EmitDynamicBoundsCheck(const Address BaseAddr,
141
141
142
142
++NumDynamicChecksRange;
143
143
144
+ // Dynamic_check(Base == NULL || (Lower <= CastLower && CastUpper <= Upper))
145
+ // Emit code blocks as follows:
146
+ // if (Base == NULL) {...}
147
+ // else {
148
+ // if (Lower <= CastLower && CastUpper <= Upper) {...}
149
+ // else { trap(); llvm_unreachable(); }
150
+ // }
151
+
152
+ Value *Cond1 =
153
+ Builder.CreateIsNull (BaseAddr.getPointer (), " _Dynamic_check.null" );
154
+
155
+ // Constant Folding:
156
+ // If we have generated a constant condition, and the condition is true,
157
+ // then the check will always pass and we can elide it.
158
+ if (const ConstantInt *ConditionConstant = dyn_cast<ConstantInt>(Cond1)) {
159
+ if (ConditionConstant->isOne ()) {
160
+ ++NumDynamicChecksElided;
161
+ return ;
162
+ }
163
+ }
164
+
165
+ ++NumDynamicChecksInserted;
166
+
167
+ BasicBlock *Begin, *DyCkSuccess, *DyCkFail, *DyCkFallThrough;
168
+ Begin = Builder.GetInsertBlock ();
169
+ DyCkSuccess = createBasicBlock (" _Dynamic_check.succeeded" );
170
+ DyCkFallThrough = createBasicBlock (" _Dynamic_check.fallthrough" , this ->CurFn );
171
+ DyCkFail = createBasicBlock (" _Dynamic_check.failed" , this ->CurFn );
172
+
173
+ Builder.SetInsertPoint (DyCkFallThrough);
144
174
// SubRange - bounds(lb, ub) vs CastRange - bounds(castlb, castub)
145
175
// Dynamic_check(lb <= castlb && castub <= ub)
146
176
@@ -169,38 +199,8 @@ void CodeGenFunction::EmitDynamicBoundsCheck(const Address BaseAddr,
169
199
Value *UpperChk =
170
200
Builder.CreateICmpULE (CastUpperInt, UpperInt, " _Dynamic_check.upper_cmp" );
171
201
172
- // if expression E is NULL, skip dynamic_check
173
- // Dynamic_check(E == NULL || (lb <= castlb && castub <= ub))
174
- // if (cond1) {...}
175
- // else {
176
- // if (cond2) {...}
177
- // else { trap(); llvm_unreachable(); }
178
- // }
179
- EmitDynamicCheckBlocks (
180
- Builder.CreateIsNull (BaseAddr.getPointer (), " _Dynamic_check.null" ),
181
- Builder.CreateAnd (LowerChk, UpperChk, " _Dynamic_check.range" ));
182
- }
183
-
184
- void CodeGenFunction::EmitDynamicCheckBlocks (Value *Condition) {
185
- assert (Condition->getType ()->isIntegerTy (1 ) &&
186
- " May only dynamic check boolean conditions" );
187
-
188
- // Constant Folding:
189
- // If we have generated a constant condition, and the condition is true,
190
- // then the check will always pass and we can elide it.
191
- if (const ConstantInt *ConditionConstant = dyn_cast<ConstantInt>(Condition)) {
192
- if (ConditionConstant->isOne ()) {
193
- ++NumDynamicChecksElided;
194
- return ;
195
- }
196
- }
197
-
198
- ++NumDynamicChecksInserted;
199
-
200
- BasicBlock *Begin, *DyCkSuccess, *DyCkFail;
201
- Begin = Builder.GetInsertBlock ();
202
- DyCkSuccess = createBasicBlock (" _Dynamic_check.succeeded" );
203
- DyCkFail = createBasicBlock (" _Dynamic_check.failed" , this ->CurFn );
202
+ Value *Cond2 = Builder.CreateAnd (LowerChk, UpperChk, " _Dynamic_check.range" );
203
+ Builder.CreateCondBr (Cond2, DyCkSuccess, DyCkFail);
204
204
205
205
Builder.SetInsertPoint (DyCkFail);
206
206
CallInst *TrapCall = Builder.CreateCall (CGM.getIntrinsic (Intrinsic::trap));
@@ -209,22 +209,21 @@ void CodeGenFunction::EmitDynamicCheckBlocks(Value *Condition) {
209
209
Builder.CreateUnreachable ();
210
210
211
211
Builder.SetInsertPoint (Begin);
212
- Builder.CreateCondBr (Condition , DyCkSuccess, DyCkFail );
212
+ Builder.CreateCondBr (Cond1 , DyCkSuccess, DyCkFallThrough );
213
213
// This ensures the success block comes directly after the branch
214
214
EmitBlock (DyCkSuccess);
215
215
216
216
Builder.SetInsertPoint (DyCkSuccess);
217
217
}
218
218
219
- // emit code for dynamic_check(cond1 || cond2)
220
- void CodeGenFunction::EmitDynamicCheckBlocks (Value *Cond1, Value *Cond2) {
221
- assert (Cond1->getType ()->isIntegerTy (1 ) &&
219
+ void CodeGenFunction::EmitDynamicCheckBlocks (Value *Condition) {
220
+ assert (Condition->getType ()->isIntegerTy (1 ) &&
222
221
" May only dynamic check boolean conditions" );
223
222
224
223
// Constant Folding:
225
224
// If we have generated a constant condition, and the condition is true,
226
225
// then the check will always pass and we can elide it.
227
- if (const ConstantInt *ConditionConstant = dyn_cast<ConstantInt>(Cond1 )) {
226
+ if (const ConstantInt *ConditionConstant = dyn_cast<ConstantInt>(Condition )) {
228
227
if (ConditionConstant->isOne ()) {
229
228
++NumDynamicChecksElided;
230
229
return ;
@@ -233,36 +232,22 @@ void CodeGenFunction::EmitDynamicCheckBlocks(Value *Cond1, Value *Cond2) {
233
232
234
233
++NumDynamicChecksInserted;
235
234
236
- // if (cond1) {...}
237
- // else {
238
- // if (cond2) {...}
239
- // else { trap(); llvm_unreachable(); }
240
- // }
241
-
242
- BasicBlock *Begin, *DyCkSuccess, *DyCkFail, *DyCkFallThrough;
235
+ BasicBlock *Begin, *DyCkSuccess, *DyCkFail;
243
236
Begin = Builder.GetInsertBlock ();
244
237
DyCkSuccess = createBasicBlock (" _Dynamic_check.succeeded" );
245
- DyCkFallThrough = createBasicBlock (" _Dynamic_check.fallthrough" , this ->CurFn );
246
238
DyCkFail = createBasicBlock (" _Dynamic_check.failed" , this ->CurFn );
247
239
248
- // if (cond1) Success
249
- // else { FallThrough
250
- // if (cond2) Success
251
- // else { Fail, trap; llvm_unreachable; }
252
- // }
253
- Builder.SetInsertPoint (DyCkFallThrough);
254
- Builder.CreateCondBr (Cond2, DyCkSuccess, DyCkFail);
255
-
256
240
Builder.SetInsertPoint (DyCkFail);
257
241
CallInst *TrapCall = Builder.CreateCall (CGM.getIntrinsic (Intrinsic::trap));
258
242
TrapCall->setDoesNotReturn ();
259
243
TrapCall->setDoesNotThrow ();
260
244
Builder.CreateUnreachable ();
261
245
262
246
Builder.SetInsertPoint (Begin);
263
- Builder.CreateCondBr (Cond1 , DyCkSuccess, DyCkFallThrough );
247
+ Builder.CreateCondBr (Condition , DyCkSuccess, DyCkFail );
264
248
// This ensures the success block comes directly after the branch
265
249
EmitBlock (DyCkSuccess);
266
250
267
251
Builder.SetInsertPoint (DyCkSuccess);
268
252
}
253
+
0 commit comments