When I execute following IR:
declare void #_puts(i32, ...)
define void #main() {
entry:
%name = alloca i32
br i1 true, label %then, label %else
then: ; preds = %entry
call void (i32, ...) #_puts(i32 1, i32 1234)
br label %end
else: ; preds = %entry
br label %end
end: ; preds = %else, %then
%if_val = phi i32 [ 1234, %then ], [ 0, %else ]
entry1: ; No predecessors!
store i32 %if_val, i32* %name
%name2 = load i32, i32* %name
call void (i32, ...) #_puts(i32 1, i32 %name2)
ret void
}
I got following error message:
Assertion failed: (!NodePtr->isKnownSentinel()), function operator*, file /Users/Mac/llvm-source/llvm/include/llvm/ADT/ilist_iterator.h, line 139.
Abort trap: 6
What does this message means?
Can anyone explain this for me?
Thanks a lot.
The message refers to a sentinel node of a simple_ilist, which is a data structure used for representing lists of functions in a module, basic blocks in a function, instructions in a basic blocks, and so on. A sentinel node represents the end of the list and is the only data member of such lists — the rest is inside the objects that constitute a list ("i" is for "intrusive").
I would guess that this message is caused by iterating over the end of a simple_ilist. Most likely the one holding the instructions in the end block, because this is the only block that is malformed. You can fix it by adding a terminator:
end: ; preds = %else, %then
%if_val = phi i32 [ 1234, %then ], [ 0, %else ]
br label %entry1
Related
this is my code:
data a ;
y = month(date()) ;
CALL SYMPUT ('y', y)
;
run ;
OPTIONS MINOPERATOR ;
%MACRO TEST;
%IF &y. NOT IN (1,4,7,10)
%THEN %DO ;
PROC SQL ;
SELECT INPUT(Legacy_Bnk_Order_Ctrl_Id,4.) INTO: parameter_acc separated by ','
FROM WORK.parameter_acc_table
;
RUN ;
%END ;
%ELSE %DO ;
%LET parameter_acc = '0' ;
%PUT ¶meter_acc. ;
%END ;
%MEND TEST;
%TEST;
I am getting the following LOG info and ERROR:
SYMBOLGEN: Macro variable Y resolves to 9
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
&y. NOT IN (1,4,7,10)
ERROR: The macro TEST will stop executing.
You cannot just insert the keyword NOT into the middle of an expression using the IN operator. Instead use it to negate the result of the IN operator.
%if NOT &y in (A,B) ...
Here is cleaned up code:
data a ;
y = month(date()) ;
CALL SYMPUTX('y', y);
run ;
%MACRO TEST / minoperator mindelimiter=',';
%IF not &y. IN (1,4,7,10) %THEN %DO ;
PROC SQL noprint;
SELECT INPUT(Legacy_Bnk_Order_Ctrl_Id,4.)
INTO :parameter_acc separated by ','
FROM WORK.parameter_acc_table
;
quit;
%END ;
%ELSE %DO ;
%LET parameter_acc = 0 ;
%END ;
%PUT ¶meter_acc. ;
%MEND TEST;
%let parameter_acc = BEFORE MACRO CALL;
%TEST;
Below is the code to execute a set of data-steps based on the value of the increment variable "i". Since I have assigned the value of i to 1 (numeric and not character value). Ideally the first data-step block need to execute, but in the below case the second data-step block is executing.
%put &i. ; prints 1 in to the log window.
%macro DSN;
%let i = 1 ;
data new_DSN;
run;
%if i = 1 %then %do;
data Dummy ;
run;
data DUMMY_ ;
set DUMMY new_DSN ;
run;
%end;
%else %if i ^= 1 %then %do ;
data DUMMY_ ;
set DUMMY_ new_DSN ;
run;
%end;
%mend DSN;
%DSN;
Your IF statement is not calling &I macro variable, but simply comparing string I to 1. This also explains why your second loop running because technically speaking string "I" is not equal to "1". You just need to put ampersand in front of I in both %IF statements. I also put two %PUT statements to easier see where code is running. See below:
%macro DSN;
%let i = 1 ;
data new_DSN;
run;
%if &i = 1 %then %do;
%PUT First Loop Run;
data Dummy ;
run;
data DUMMY_ ;
set DUMMY new_DSN ;
run;
%end;
%else %if &i ^= 1 %then %do ;
%PUT Second Loop Run;
data DUMMY_ ;
set DUMMY_ new_DSN ;
run;
%end;
%mend DSN;
%DSN;
I've been reading up on how to DROP variables from my dataset that have null values in every observation - it seems the best way to do this is using the %DROPMISS macro function - however I'm getting an error msg - below is the code I'm trying and the error msg
Code
%DROPMISS (DSIN=dataset1, DSOUT=dataset2);
Log
4665 %DROPMISS (DSIN=dataset1, DSOUT=dataset2);
-
180
WARNING: Apparent invocation of macro DROPMISS not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order.
You need to define the dropmiss macro before you use it.
You can find it here in the appendix (page3)
http://support.sas.com/resources/papers/proceedings10/048-2010.pdf
Or better formatted here:
/******************/
options nomprint noSYMBOLGEN MLOGIC;
/****************************/
%macro DROPMISS( DSNIN /* name of input SAS dataset
*/
, DSNOUT /* name of output SAS dataset
*/
, NODROP= /* [optional] variables to be omitted from dropping even if
they have only missing values */
) ;
/* PURPOSE: To find both Character and Numeric the variables that have only
missing values and drop them if
* they are not in &NONDROP
*
* NOTE: if there are no variables in the dataset, produce no variables
processing code
*
*
* EXAMPLE OF USE:
* %DROPMISS( DSNIN, DSNOUT )
* %DROPMISS( DSNIN, DSNOUT, NODROP=A B C D--H X1-X100 )
* %DROPMISS( DSNIN, DSNOUT, NODROP=_numeric_ )
* %DROPMISS( DSNIN, DSNOUT, NOdrop=_character_ )
*/
%local I ;
%if "&DSNIN" = "&DSNOUT"
%then %do ;
%put /------------------------------------------------\ ;
%put | ERROR from DROPMISS: | ;
%put | Input Dataset has same name as Output Dataset. | ;
%put | Execution terminating forthwith. | ;
%put \------------------------------------------------/ ;
%goto L9999 ;
%end ;
/*###################################################################*/
/* begin executable code
/*####################################################################/
/*===================================================================*/
/* Create dataset of variable names that have only missing values
/* exclude from the computation all names in &NODROP
/*===================================================================*/
proc contents data=&DSNIN( drop=&NODROP ) memtype=data noprint out=_cntnts_( keep=
name type ) ; run ;
%let N_CHAR = 0 ;
%let N_NUM = 0 ;
data _null_ ;
set _cntnts_ end=lastobs nobs=nobs ;
if nobs = 0 then stop ;
n_char + ( type = 2 ) ;
n_num + ( type = 1 ) ;
/* create macro vars containing final # of char, numeric variables */
if lastobs
then do ;
call symput( 'N_CHAR', left( put( n_char, 5. ))) ;
call symput( 'N_NUM' , left( put( n_num , 5. ))) ;
end ;
run ;
/*===================================================================*/
/* if there are no variables in dataset, stop further processing
/*===================================================================*/
%if %eval( &N_NUM + &N_CHAR ) = 0
%then %do ;
%put /----------------------------------\ ;
%put | ERROR from DROPMISS: | ;
%put | No variables in dataset. | ;
%put | Execution terminating forthwith. | ;
%put \----------------------------------/ ;
%goto L9999 ;
%end ;
/*===================================================================*/
/* put global macro names into global symbol table for later retrieval
/*===================================================================*/
%LET NUM0 =0;
%LET CHAR0 = 0;
%IF &N_NUM >0 %THEN %DO;
%do I = 1 %to &N_NUM ;
%global NUM&I ;
%end ;
%END;
%if &N_CHAR > 0 %THEN %DO;
%do I = 1 %to &N_CHAR ;
%global CHAR&I ;
%end ;
%END;
/*===================================================================*/
/* create macro vars containing variable names
/* efficiency note: could compute n_char, n_num here, but must declare macro names
to be
global b4 stuffing them
/*
/*===================================================================*/
proc sql noprint ;
%if &N_CHAR > 0 %then %str( select name into :CHAR1 - :CHAR&N_CHAR from
_cntnts_ where type = 2 ; ) ;
%if &N_NUM > 0 %then %str( select name into :NUM1 - :NUM&N_NUM from
_cntnts_ where type = 1 ; ) ;
quit ;
/*===================================================================*/
/* Determine the variables that are missing
/*
/*===================================================================*/
%IF &N_CHAR > 1 %THEN %DO;
%let N_CHAR_1 = %EVAL(&N_CHAR - 1);
%END;
Proc sql ;
select %do I= 1 %to &N_NUM; max (&&NUM&I) , %end; %IF &N_CHAR > 1 %THEN %DO;
%do I= 1 %to &N_CHAR_1; max(&&CHAR&I), %END; %end; MAX(&&CHAR&N_CHAR)
into
%do I= 1 %to &N_NUM; :NUMMAX&I , %END; %IF &N_CHAR > 1 %THEN %DO;
%do I= 1 %to &N_CHAR_1; :CHARMAX&I,%END; %END; :CHARMAX&N_CHAR
from &DSNIN;
quit;
/*===================================================================*/
/* initialize DROP_NUM, DROP_CHAR global macro vars
/*===================================================================*/
%let DROP_NUM = ;
%let DROP_CHAR = ;
%if &N_NUM > 0 %THEN %DO;
DATA _NULL_;
%do I = 1 %to &N_NUM ;
%IF &&NUMMAX&I =. %THEN %DO;
%let DROP_NUM = &DROP_NUM %qtrim( &&NUM&I ) ;
%END;
%end ;
RUN;
%END;
%IF &N_CHAR > 0 %THEN %DO;
DATA _NULL_;
%do I = 1 %to &N_CHAR ;
%IF "%qtrim(&&CHARMAX&I)" eq "" %THEN %DO;
%let DROP_CHAR = &DROP_CHAR %qtrim( &&CHAR&I ) ;
%END;
%end ;
RUN;
%END;
/*===================================================================*/
/* Create output dataset
/*===================================================================*/
data &DSNOUT ;
%if &DROP_CHAR ^= %then %str(DROP &DROP_CHAR ; ) ; /* drop char variables
that
have only missing values */
%if &DROP_NUM ^= %then %str(DROP &DROP_NUM ; ) ; /* drop num variables
that
have only missing values */
set &DSNIN ;
%if &DROP_CHAR ^= or &DROP_NUM ^= %then %do;
%put /----------------------------------\ ;
%put | Variables dropped are &DROP_CHAR &DROP_NUM | ;
%put \----------------------------------/ ;
%end;
%if &DROP_CHAR = and &DROP_NUM = %then %do;
%put /----------------------------------\ ;
%put | No variables are dropped |;
%put \----------------------------------/ ;
%end;
run ;
%L9999:
%mend DROPMISS ;
For a Macro, I want to create an automated ATTRIB Statement.
I have an exel Table with all variable names, formats, lables and lengths.
Now I want SAS to read each row and pass it into:
%LET Format_VARIABLE = FORMAT = &For LENGTH = &len LABEL = "&lab";
Any ideas how to archive this?
Assuming you have a dataset (called metadata) containing all of you variable names (vname), formats (vfmt), lengths (vlen) and labels (vlbl) from Excel :
/* Create VNAME1-VNAMEx, VFMT1-VFMTx etc */
data _null_ ;
set metadata end=eof ;
call symputx(cats('VNAME',_n_),vname) ;
call symputx(cats('VFMT',_n_),vfmt) ;
call symputx(cats('VLEN',_n_),vlen) ;
call symputx(cats('VLBL',_n_),vlbl) ;
if eof then call symputx('VNUM',_n_) ;
run ;
%MACRO BUILD_ATTRIB ;
/* Iterate over each set of macro variables and resolve into `attrib` statement */
attrib %DO I = 1 %TO &VNUM ;
&&VNAME&I format=&&VFMT&I length=&&VLEN&I label="&&VLBL&I"
%END ;
;
%MEND ;
/* To use in a datastep */
data want ;
%BUILD_ATTRIB ;
set have ;
run ;
in my pass I inspect the penultimate instruction from every basic block in runOnFunction(). I am interested in ICMP instructions only.
if(BB->size()>1)
if(last->getPrevNode())
{
previous = last->getPrevNode();
ok=1;
}
I want to get the operands of previous, which is of type Instruction*. Due tests based on getNumOperands, ICMP has 2 (as normal).
if ( ok && ((previous->getNumOperands())>=2) )
errs()<<"\nTTTTT "<<previous->getOperand(0)->getName()<<" | "
<<previous->getOperand(0)->getValueName()<<" | "
<<previous->getOperand(0)->getValueID()<<" | "
<<previous->getOperand(0)->getNumUses()<<" TTTTT\n";
The results with getOperand(1) are similar.
The output is:
*PREVIOUS: store i32 %conv15, i32* %i, align 4
TTTTT conv15 | 0x9b69090 | 59 | 1 TTTTT
...
*PREVIOUS: store i32 %inc13, i32* %i, align 4
TTTTT inc13 | 0x9b76478 | 30 | 1 TTTTT
...
*PREVIOUS: %cmp11 = icmp sgt i32 %8, 3
TTTTT | 0x0 | 49 | 1 TTTTT
...
*PREVIOUS: store i32 %dec, i32* %i, align 4
TTTTT dec | 0x9b69130 | 30 | 1 TTTTT
...
*PREVIOUS: %cmp8 = icmp sle i32 %6, 2
TTTTT | 0x0 | 49 | 1 TTTTT
...
*PREVIOUS: store i32 %inc, i32* %i, align 4
TTTTT inc | 0x9b761c8 | 30 | 1 TTTTT
Do you know how I can get the operands from ICMP instructions? I need to use them in some conditions? (also their attributes).
Thank you a lot !
You ask:
Do you know how I can get the operands from ICMP instructions
But you did get the operands, you can use those values just fine. In your specific examples they don't have a name (numbered values such as %8 are considered nameless, and constants are obviously nameless), but they are still valid values.