The purpose of do{ ... } while(0) construct is to turn a group of statements into a single compound statement that can be terminated with a ;. You see, in C language the do/while construct has one weird and unusual property: even though it "works" as a compound statement, it expects a ; at the end. No other compound constructs in C have this property.
Because of this property, you can use do/while to write multi-statement macros, which can be safely used as "ordinary" functions without worrying what's inside the macro, as in the following example
if (/* some condition */)
__local_irq_save(x); /* <- we can safely put `;` here */
else
/* whatever */;